Fixes POM, and moves things around
This commit is contained in:
@ -0,0 +1,15 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
public enum DisallowCause {
|
||||
// -------------------------------------------- //
|
||||
// ENUM
|
||||
// -------------------------------------------- //
|
||||
|
||||
PEACEFUL_LAND,
|
||||
FACTIONLESS,
|
||||
FRIENDLYFIRE,
|
||||
OWN_TERRITORY
|
||||
|
||||
// END OF LIST
|
||||
|
||||
}
|
@ -0,0 +1,269 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MFlag;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.factions.event.EventFactionsPvpDisallowed;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.AreaEffectCloudApplyEvent;
|
||||
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.PotionSplashEvent;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EngineCanCombatHappen extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineCanCombatHappen i = new EngineCanCombatHappen();
|
||||
|
||||
public static EngineCanCombatHappen get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CAN COMBAT DAMAGE HAPPEN
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void canCombatDamageHappen(EntityDamageByEntityEvent event) {
|
||||
if (this.canCombatDamageHappen(event, true)) {
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
|
||||
Entity damager = event.getDamager();
|
||||
if (damager instanceof Arrow && !(damager instanceof Trident)) {
|
||||
damager.remove();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 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) {
|
||||
EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent(event.getCombuster(), event.getEntity(), EntityDamageEvent.DamageCause.FIRE, 0D);
|
||||
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;
|
||||
}
|
||||
|
||||
ProjectileSource projectileSource = event.getPotion().getShooter();
|
||||
if (!(projectileSource instanceof Entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity thrower = (Entity) projectileSource;
|
||||
|
||||
// ... scan through affected entities to make sure they're all valid targets.
|
||||
for (LivingEntity affectedEntity : event.getAffectedEntities()) {
|
||||
EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent(thrower, affectedEntity, EntityDamageEvent.DamageCause.CUSTOM, 0D);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void canCombatDamageHappen(AreaEffectCloudApplyEvent event) {
|
||||
// If a harmful potion effect cloud is present ...
|
||||
if (!MUtil.isHarmfulPotion(event.getEntity().getBasePotionData().getType().getEffectType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectileSource projectileSource = event.getEntity().getSource();
|
||||
if (!(projectileSource instanceof Entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity thrower = (Entity) projectileSource;
|
||||
|
||||
// ... create a dummy list to avoid ConcurrentModificationException ...
|
||||
List<LivingEntity> affectedList = new ArrayList<>();
|
||||
|
||||
// ... then scan through affected entities to make sure they're all valid targets ...
|
||||
for (LivingEntity affectedEntity : event.getAffectedEntities()) {
|
||||
EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent(thrower, affectedEntity, EntityDamageEvent.DamageCause.CUSTOM, 0D);
|
||||
// Notification disabled due to the iterating nature of effect clouds.
|
||||
if (EngineCanCombatHappen.get().canCombatDamageHappen(sub, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
affectedList.add(affectedEntity);
|
||||
}
|
||||
|
||||
// finally, remove valid targets from the affected list. (Unlike splash potions, area effect cloud's affected entities list is mutable.)
|
||||
event.getAffectedEntities().removeAll(affectedList);
|
||||
}
|
||||
|
||||
// Utility method used in "canCombatDamageHappen" below.
|
||||
public static boolean falseUnlessDisallowedPvpEventCancelled(Player attacker, Player defender, DisallowCause reason, EntityDamageByEntityEvent event) {
|
||||
EventFactionsPvpDisallowed dpe = new EventFactionsPvpDisallowed(attacker, defender, reason, event);
|
||||
dpe.run();
|
||||
return dpe.isCancelled();
|
||||
}
|
||||
|
||||
public boolean canCombatDamageHappen(EntityDamageByEntityEvent event, boolean notify) {
|
||||
boolean ret = true;
|
||||
|
||||
// If the defender is a player ...
|
||||
Entity edefender = event.getEntity();
|
||||
if (MUtil.isntPlayer(edefender)) {
|
||||
return true;
|
||||
}
|
||||
Player defender = (Player) edefender;
|
||||
MPlayer mdefender = MPlayer.get(edefender);
|
||||
|
||||
// ... and the attacker is someone else ...
|
||||
Entity eattacker = MUtil.getLiableDamager(event);
|
||||
|
||||
// (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;
|
||||
}
|
||||
|
||||
// ... gather defender PS and faction information ...
|
||||
PS defenderPs = PS.valueOf(defender.getLocation());
|
||||
Faction defenderPsFaction = BoardColl.get().getFactionAt(defenderPs);
|
||||
|
||||
// ... fast evaluate if the attacker is overriding ...
|
||||
if (MUtil.isPlayer(eattacker)) {
|
||||
|
||||
MPlayer mplayer = MPlayer.get(eattacker);
|
||||
if (mplayer != null && mplayer.isOverriding()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// ... PVP flag may cause a damage block ...
|
||||
if (defenderPsFaction.getFlag(MFlag.getFlagPvp()) == false) {
|
||||
if (eattacker == null) {
|
||||
// No attacker?
|
||||
// Let's behave as if it were a player
|
||||
return falseUnlessDisallowedPvpEventCancelled(null, defender, DisallowCause.PEACEFUL_LAND, event);
|
||||
}
|
||||
if (MUtil.isPlayer(eattacker)) {
|
||||
ret = falseUnlessDisallowedPvpEventCancelled((Player) eattacker, defender, DisallowCause.PEACEFUL_LAND, event);
|
||||
if (!ret && notify) {
|
||||
MPlayer attacker = MPlayer.get(eattacker);
|
||||
attacker.msg("<i>PVP is disabled in %s.", defenderPsFaction.describeTo(attacker));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return defenderPsFaction.getFlag(MFlag.getFlagMonsters());
|
||||
}
|
||||
|
||||
// ... and if the attacker is a player ...
|
||||
if (MUtil.isntPlayer(eattacker)) {
|
||||
return true;
|
||||
}
|
||||
Player attacker = (Player) eattacker;
|
||||
MPlayer uattacker = MPlayer.get(attacker);
|
||||
|
||||
// ... does this player bypass all protection? ...
|
||||
if (MConf.get().playersWhoBypassAllProtection.contains(attacker.getName())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ... gather attacker PS and faction information ...
|
||||
PS attackerPs = PS.valueOf(attacker.getLocation());
|
||||
Faction attackerPsFaction = BoardColl.get().getFactionAt(attackerPs);
|
||||
|
||||
// ... 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.
|
||||
if (attackerPsFaction.getFlag(MFlag.getFlagPvp()) == false) {
|
||||
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, DisallowCause.PEACEFUL_LAND, event);
|
||||
if (!ret && notify) {
|
||||
uattacker.msg("<i>PVP is disabled in %s.", attackerPsFaction.describeTo(uattacker));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ... are PVP rules completely ignored in this world? ...
|
||||
if (!MConf.get().worldsPvpRulesEnabled.contains(defenderPs.getWorld())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Faction defendFaction = mdefender.getFaction();
|
||||
Faction attackFaction = uattacker.getFaction();
|
||||
|
||||
if (attackFaction.isNone() && MConf.get().disablePVPForFactionlessPlayers) {
|
||||
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, DisallowCause.FACTIONLESS, event);
|
||||
if (!ret && notify) {
|
||||
uattacker.msg("<i>You can't hurt other players until you join a faction.");
|
||||
}
|
||||
return ret;
|
||||
} else if (defendFaction.isNone()) {
|
||||
if (defenderPsFaction == attackFaction && MConf.get().enablePVPAgainstFactionlessInAttackersLand) {
|
||||
// Allow PVP vs. Factionless in attacker's faction territory
|
||||
return true;
|
||||
} else if (MConf.get().disablePVPForFactionlessPlayers) {
|
||||
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, DisallowCause.FACTIONLESS, event);
|
||||
if (!ret && notify) {
|
||||
uattacker.msg("<i>You can't hurt players who are not currently in a faction.");
|
||||
}
|
||||
return ret;
|
||||
} else if (attackFaction.isNone() && MConf.get().enablePVPBetweenFactionlessPlayers) {
|
||||
// Allow factionless vs factionless
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Rel relation = defendFaction.getRelationTo(attackFaction);
|
||||
|
||||
// Check the relation
|
||||
if (relation.isFriend() && defenderPsFaction.getFlag(MFlag.getFlagFriendlyire()) == false) {
|
||||
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, DisallowCause.FRIENDLYFIRE, event);
|
||||
if (!ret && notify) {
|
||||
uattacker.msg("<i>You can't hurt %s<i>.", relation.getDescPlayerMany());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// You can not hurt neutrals in their own territory.
|
||||
boolean ownTerritory = mdefender.isInOwnTerritory();
|
||||
|
||||
if (mdefender.hasFaction() && ownTerritory && relation == Rel.NEUTRAL) {
|
||||
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, DisallowCause.OWN_TERRITORY, event);
|
||||
if (!ret && notify) {
|
||||
uattacker.msg("<i>You can't hurt %s<i> in their own territory unless you declare them as an enemy.", mdefender.describeTo(uattacker));
|
||||
mdefender.msg("%s<i> tried to hurt you.", uattacker.describeTo(mdefender, true));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
166
src/main/java/com/massivecraft/factions/engine/EngineChat.java
Normal file
166
src/main/java/com/massivecraft/factions/engine/EngineChat.java
Normal file
@ -0,0 +1,166 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.RelationParticipator;
|
||||
import com.massivecraft.factions.chat.ChatFormatter;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.event.EventMassiveCorePlayerToRecipientChat;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.plugin.EventExecutor;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class EngineChat extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineChat i = new EngineChat();
|
||||
|
||||
public static EngineChat get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
public EngineChat() {
|
||||
this.setPlugin(Factions.get());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public void setActiveInner(boolean active) {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (MConf.get().chatSetFormat) {
|
||||
Bukkit.getPluginManager().registerEvent(AsyncPlayerChatEvent.class, this, MConf.get().chatSetFormatAt, new SetFormatEventExecutor(), Factions.get(), true);
|
||||
}
|
||||
|
||||
if (MConf.get().chatParseTags) {
|
||||
Bukkit.getPluginManager().registerEvent(AsyncPlayerChatEvent.class, this, MConf.get().chatParseTagsAt, new ParseTagsEventExecutor(), Factions.get(), true);
|
||||
}
|
||||
|
||||
if (MConf.get().chatParseTags) {
|
||||
Bukkit.getPluginManager().registerEvent(EventMassiveCorePlayerToRecipientChat.class, this, EventPriority.NORMAL, new ParseRelcolorEventExecutor(), Factions.get(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// SET FORMAT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private class SetFormatEventExecutor implements EventExecutor {
|
||||
@Override
|
||||
public void execute(Listener listener, Event event) throws EventException {
|
||||
try {
|
||||
if (!(event instanceof AsyncPlayerChatEvent)) {
|
||||
return;
|
||||
}
|
||||
setFormat((AsyncPlayerChatEvent) event);
|
||||
} catch (Throwable t) {
|
||||
throw new EventException(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setFormat(AsyncPlayerChatEvent event) {
|
||||
event.setFormat(MConf.get().chatSetFormatTo);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// PARSE TAGS
|
||||
// -------------------------------------------- //
|
||||
|
||||
private class ParseTagsEventExecutor implements EventExecutor {
|
||||
@Override
|
||||
public void execute(Listener listener, Event event) throws EventException {
|
||||
try {
|
||||
if (!(event instanceof AsyncPlayerChatEvent)) {
|
||||
return;
|
||||
}
|
||||
parseTags((AsyncPlayerChatEvent) event);
|
||||
} catch (Throwable t) {
|
||||
throw new EventException(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseTags(AsyncPlayerChatEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (MUtil.isntPlayer(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String format = event.getFormat();
|
||||
format = ChatFormatter.format(format, player, null);
|
||||
event.setFormat(format);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// PARSE RELCOLOR
|
||||
// -------------------------------------------- //
|
||||
|
||||
private class ParseRelcolorEventExecutor implements EventExecutor {
|
||||
@Override
|
||||
public void execute(Listener listener, Event event) throws EventException {
|
||||
try {
|
||||
if (!(event instanceof EventMassiveCorePlayerToRecipientChat)) {
|
||||
return;
|
||||
}
|
||||
parseRelcolor((EventMassiveCorePlayerToRecipientChat) event);
|
||||
} catch (Throwable t) {
|
||||
throw new EventException(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseRelcolor(EventMassiveCorePlayerToRecipientChat event) {
|
||||
String format = event.getFormat();
|
||||
format = ChatFormatter.format(format, event.getSender(), event.getRecipient());
|
||||
event.setFormat(format);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FILTER CHAT CHANNEL
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static Predicate<Player> getPredicateIsInFaction(RelationParticipator participator) {
|
||||
return player -> MPlayer.get(player).getRelationTo(participator).isAtLeast(Rel.FACTION);
|
||||
}
|
||||
|
||||
public static Predicate<Player> getPredicateIsAlly(RelationParticipator participator) {
|
||||
return player -> MPlayer.get(player).getFaction().getRelationTo(participator).isAtLeast(Rel.ALLY);
|
||||
}
|
||||
|
||||
public static void filterToPredicate(AsyncPlayerChatEvent event, Predicate<Player> predicate) {
|
||||
Player player = event.getPlayer();
|
||||
MPlayer mplayer = MPlayer.get(player);
|
||||
Faction faction = mplayer.getFaction();
|
||||
|
||||
// Get and filter recipients
|
||||
for (Iterator<Player> it = event.getRecipients().iterator(); it.hasNext(); ) {
|
||||
Player recipient = it.next();
|
||||
if (predicate.test(recipient)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,270 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.FactionColl;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MFlag;
|
||||
import com.massivecraft.factions.entity.MPerm;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.factions.event.EventFactionsChunksChange;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.collections.MassiveList;
|
||||
import com.massivecraft.massivecore.collections.MassiveSet;
|
||||
import com.massivecraft.massivecore.mixin.MixinWorld;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
public class EngineChunkChange extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineChunkChange i = new EngineChunkChange();
|
||||
|
||||
public static EngineChunkChange get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CHUNK CHANGE: ALLOWED
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onChunksChange(EventFactionsChunksChange event) {
|
||||
// For security reasons we block the chunk change on any error since an error might block security checks from happening.
|
||||
try {
|
||||
onChunksChangeInner(event);
|
||||
} catch (Throwable throwable) {
|
||||
event.setCancelled(true);
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void onChunksChangeInner(EventFactionsChunksChange event) {
|
||||
// Args
|
||||
final MPlayer mplayer = event.getMPlayer();
|
||||
final Faction newFaction = event.getNewFaction();
|
||||
final Map<Faction, Set<PS>> currentFactionChunks = event.getOldFactionChunks();
|
||||
final Set<Faction> currentFactions = currentFactionChunks.keySet();
|
||||
final Set<PS> chunks = event.getChunks();
|
||||
|
||||
// Override Mode? Sure!
|
||||
if (mplayer.isOverriding()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// CALC: Is there at least one normal faction among the current ones?
|
||||
boolean currentFactionsContainsAtLeastOneNormal = false;
|
||||
for (Faction currentFaction : currentFactions) {
|
||||
if (currentFaction.isNormal()) {
|
||||
currentFactionsContainsAtLeastOneNormal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the new faction is normal (not wilderness/none), meaning if we are claiming for a faction ...
|
||||
if (newFaction.isNormal()) {
|
||||
// ... ensure claiming is enabled for the worlds of all chunks ...
|
||||
for (PS chunk : chunks) {
|
||||
String worldId = chunk.getWorld();
|
||||
if (!MConf.get().worldsClaimingEnabled.contains(worldId)) {
|
||||
String worldName = MixinWorld.get().getWorldDisplayName(worldId);
|
||||
mplayer.msg("<b>Land claiming is disabled in <h>%s<b>.", worldName);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ... ensure we have permission to alter the territory of the new faction ...
|
||||
if (!MPerm.getPermTerritory().has(mplayer, newFaction, true)) {
|
||||
// NOTE: No need to send a message. We send message from the permission check itself.
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... ensure the new faction has enough players to claim ...
|
||||
if (newFaction.getMPlayers().size() < MConf.get().claimsRequireMinFactionMembers) {
|
||||
mplayer.msg("<b>Factions must have at least <h>%s<b> members to claim land.", MConf.get().claimsRequireMinFactionMembers);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
int claimedLandCount = newFaction.getLandCount();
|
||||
if (!newFaction.getFlag(MFlag.getFlagInfpower())) {
|
||||
// ... ensure the claim would not bypass the global max limit ...
|
||||
if (MConf.get().claimedLandsMax != 0 && claimedLandCount + chunks.size() > MConf.get().claimedLandsMax) {
|
||||
mplayer.msg("<b>Limit reached. You can't claim more land.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... ensure the claim would not bypass the global world limit ...
|
||||
if (MConf.get().claimedWorldsMax >= 0) {
|
||||
Set<String> oldWorlds = newFaction.getClaimedWorlds();
|
||||
Set<String> newWorlds = PS.getDistinctWorlds(chunks);
|
||||
|
||||
Set<String> worlds = new MassiveSet<>();
|
||||
worlds.addAll(oldWorlds);
|
||||
worlds.addAll(newWorlds);
|
||||
|
||||
if (!oldWorlds.containsAll(newWorlds) && worlds.size() > MConf.get().claimedWorldsMax) {
|
||||
List<String> worldNames = new MassiveList<>();
|
||||
for (String world : oldWorlds) {
|
||||
worldNames.add(MixinWorld.get().getWorldDisplayName(world));
|
||||
}
|
||||
|
||||
String worldsMax = MConf.get().claimedWorldsMax == 1 ? "world" : "worlds";
|
||||
String worldsAlready = oldWorlds.size() == 1 ? "world" : "worlds";
|
||||
mplayer.msg("<b>A faction may only be present on <h>%d<b> different %s.", MConf.get().claimedWorldsMax, worldsMax);
|
||||
mplayer.msg("%s<i> is already present on <h>%d<i> %s:", newFaction.describeTo(mplayer), oldWorlds.size(), worldsAlready);
|
||||
mplayer.message(Txt.implodeCommaAndDot(worldNames, ChatColor.YELLOW.toString()));
|
||||
mplayer.msg("<i>Please unclaim bases on other worlds to claim here.");
|
||||
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ... ensure the claim would not bypass the faction power ...
|
||||
if (claimedLandCount + chunks.size() > newFaction.getPowerRounded()) {
|
||||
mplayer.msg("<b>You don't have enough power to claim that land.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... ensure the claim would not violate distance to neighbors ...
|
||||
// HOW: Calculate the factions nearby, excluding the chunks themselves, the faction itself and the wilderness faction.
|
||||
// HOW: The chunks themselves will be handled in the "if (oldFaction.isNormal())" section below.
|
||||
Set<PS> nearbyChunks = BoardColl.getNearbyChunks(chunks, MConf.get().claimMinimumChunksDistanceToOthers);
|
||||
nearbyChunks.removeAll(chunks);
|
||||
Set<Faction> nearbyFactions = BoardColl.getDistinctFactions(nearbyChunks);
|
||||
nearbyFactions.remove(FactionColl.get().getNone());
|
||||
nearbyFactions.remove(newFaction);
|
||||
// HOW: Next we check if the new faction has permission to claim nearby the nearby factions.
|
||||
MPerm claimnear = MPerm.getPermClaimnear();
|
||||
for (Faction nearbyFaction : nearbyFactions) {
|
||||
if (claimnear.has(mplayer, nearbyFaction, true)) {
|
||||
continue;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... ensure claims are properly connected ...
|
||||
if
|
||||
(
|
||||
// If claims must be connected ...
|
||||
MConf.get().claimsMustBeConnected
|
||||
// ... and this faction already has claimed something on this map (meaning it's not their first claim) ...
|
||||
&&
|
||||
newFaction.getLandCountInWorld(chunks.iterator().next().getWorld()) > 0
|
||||
// ... and none of the chunks are connected to an already claimed chunk for the faction ...
|
||||
&&
|
||||
!BoardColl.get().isAnyConnectedPs(chunks, newFaction)
|
||||
// ... and either claims must always be connected or there is at least one normal faction among the old factions ...
|
||||
&&
|
||||
(!MConf.get().claimsCanBeUnconnectedIfOwnedByOtherFaction || currentFactionsContainsAtLeastOneNormal)
|
||||
) {
|
||||
if (MConf.get().claimsCanBeUnconnectedIfOwnedByOtherFaction) {
|
||||
mplayer.msg("<b>You can only claim additional land which is connected to your first claim or controlled by another faction!");
|
||||
} else {
|
||||
mplayer.msg("<b>You can only claim additional land which is connected to your first claim!");
|
||||
}
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure claims are properly connected when unclaiming
|
||||
if (newFaction.isNone() && MConf.get().claimsMustBeConnected && MConf.get().claimsMustBeConnectedStrict) {
|
||||
for (Entry<Faction, Set<PS>> entry : currentFactionChunks.entrySet()) {
|
||||
Faction faction = entry.getKey();
|
||||
Set<PS> factionRemovedChunks = entry.getValue();
|
||||
|
||||
Set<PS> pssBefore = BoardColl.get().getChunks(faction);
|
||||
|
||||
// Get how many "forests" of claims there are right now
|
||||
List<Collection<PS>> forestsBefore = BoardColl.getForests(pssBefore);
|
||||
|
||||
Set<PS> pssAfter = new MassiveSet<>(pssBefore);
|
||||
pssAfter.removeAll(factionRemovedChunks);
|
||||
|
||||
List<Collection<PS>> forestsAfter = BoardColl.getForests(pssAfter);
|
||||
if (forestsAfter.size() > forestsBefore.size()) {
|
||||
mplayer.msg("<b>Claims must be connected. You can't make them disconnected by unclaiming.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For each of the old factions ...
|
||||
for (Entry<Faction, Set<PS>> entry : currentFactionChunks.entrySet()) {
|
||||
Faction oldFaction = entry.getKey();
|
||||
Set<PS> oldChunks = entry.getValue();
|
||||
|
||||
// ... that is an actual faction ...
|
||||
if (oldFaction.isNone()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ... for which the mplayer lacks permission ...
|
||||
if (MPerm.getPermTerritory().has(mplayer, oldFaction, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ... consider all reasons to forbid "overclaiming/warclaiming" ...
|
||||
|
||||
// ... claiming from others may be forbidden ...
|
||||
if (!MConf.get().claimingFromOthersAllowed) {
|
||||
mplayer.msg("<b>You may not claim land from others.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and they must actually be claiming ...
|
||||
if (newFaction.isNone()) {
|
||||
mplayer.msg("<b>You can't unclaim land belonging to others.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... the relation may forbid ...
|
||||
if (oldFaction.getRelationTo(newFaction).isAtLeast(Rel.TRUCE)) {
|
||||
mplayer.msg("<b>You can't claim this land due to your relation with the current owner.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... the old faction might not be inflated enough ...
|
||||
if (oldFaction.getPowerRounded() > oldFaction.getLandCount() - oldChunks.size() && MConf.get().claimingFromOthersMustBeInflated) {
|
||||
mplayer.msg("%s<i> owns this land and is strong enough to keep it.", oldFaction.getName(mplayer));
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and you might be trying to claim without starting at the border ...
|
||||
if (!BoardColl.get().isAnyBorderPs(chunks)) {
|
||||
mplayer.msg("<b>You must start claiming land at the border of the territory.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... otherwise you may claim from this old faction even though you lack explicit permission from them.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.factions.entity.MPlayerColl;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.event.EventMassiveCorePlayerCleanInactivityToleranceMillis;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class EngineCleanInactivity extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineCleanInactivity i = new EngineCleanInactivity();
|
||||
|
||||
public static EngineCleanInactivity get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// REMOVE PLAYER MILLIS
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void ageBonus(EventMassiveCorePlayerCleanInactivityToleranceMillis event) {
|
||||
if (event.getColl() != MPlayerColl.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyPlayerAgeBonus(event);
|
||||
applyFactionAgeBonus(event);
|
||||
}
|
||||
|
||||
public void applyPlayerAgeBonus(EventMassiveCorePlayerCleanInactivityToleranceMillis event) {
|
||||
// Calculate First Played
|
||||
Long firstPlayed = event.getEntity().getFirstPlayed();
|
||||
Long age = 0L;
|
||||
if (firstPlayed != null) {
|
||||
age = System.currentTimeMillis() - firstPlayed;
|
||||
}
|
||||
|
||||
// Calculate the Bonus!
|
||||
Long bonus = calculateBonus(age, MConf.get().cleanInactivityToleranceMillisPlayerAgeToBonus);
|
||||
if (bonus == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply
|
||||
event.getToleranceCauseMillis().put("Player Age Bonus", bonus);
|
||||
}
|
||||
|
||||
public void applyFactionAgeBonus(EventMassiveCorePlayerCleanInactivityToleranceMillis event) {
|
||||
// Calculate Faction Age
|
||||
Faction faction = ((MPlayer) event.getEntity()).getFaction();
|
||||
long age = 0L;
|
||||
if (!faction.isNone()) {
|
||||
age = faction.getAge();
|
||||
}
|
||||
|
||||
// Calculate the Bonus!
|
||||
Long bonus = calculateBonus(age, MConf.get().cleanInactivityToleranceMillisFactionAgeToBonus);
|
||||
if (bonus == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply
|
||||
event.getToleranceCauseMillis().put("Faction Age Bonus", bonus);
|
||||
}
|
||||
|
||||
private Long calculateBonus(long age, Map<Long, Long> ageToBonus) {
|
||||
if (ageToBonus.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Long bonus = 0L;
|
||||
for (Entry<Long, Long> entry : ageToBonus.entrySet()) {
|
||||
Long key = entry.getKey();
|
||||
if (key == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Long value = entry.getValue();
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (age >= key) {
|
||||
bonus = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return bonus;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MFlag;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EngineDenyCommands extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineDenyCommands i = new EngineDenyCommands();
|
||||
|
||||
public static EngineDenyCommands get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// 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();
|
||||
if (MUtil.isntPlayer(player)) {
|
||||
return;
|
||||
}
|
||||
MPlayer mplayer = MPlayer.get(player);
|
||||
|
||||
// ... and the player is not overriding ...
|
||||
if (mplayer.isOverriding()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... clean up the command ...
|
||||
String command = event.getMessage();
|
||||
command = Txt.removeLeadingCommandDust(command);
|
||||
command = command.toLowerCase();
|
||||
command = command.trim();
|
||||
|
||||
// ... the command may be denied for members of permanent factions ...
|
||||
if (mplayer.hasFaction() && mplayer.getFaction().getFlag(MFlag.getFlagPermanent()) && MUtil.containsCommand(command, MConf.get().denyCommandsPermanentFactionMember)) {
|
||||
mplayer.msg("<b>You can't use \"<h>/%s<b>\" as member of a permanent faction.", command);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... if there is a faction at the players location we fetch the relation now ...
|
||||
PS ps = PS.valueOf(player.getLocation()).getChunk(true);
|
||||
Faction factionAtPs = BoardColl.get().getFactionAt(ps);
|
||||
Rel factionAtRel = null;
|
||||
|
||||
if (factionAtPs != null && !factionAtPs.isNone()) {
|
||||
factionAtRel = factionAtPs.getRelationTo(mplayer);
|
||||
}
|
||||
|
||||
// ... there maybe be a player in the distance that denies the command ...
|
||||
if (MConf.get().denyCommandsDistance > -1 && !MConf.get().denyCommandsDistanceBypassIn.contains(factionAtRel)) {
|
||||
for (Player otherplayer : player.getWorld().getPlayers()) {
|
||||
MPlayer othermplayer = MPlayer.get(otherplayer);
|
||||
if (othermplayer == mplayer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double distance = player.getLocation().distance(otherplayer.getLocation());
|
||||
if (MConf.get().denyCommandsDistance > distance) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Rel playerRel = mplayer.getRelationTo(othermplayer);
|
||||
if (!MConf.get().denyCommandsDistanceRelation.containsKey(playerRel)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String desc = playerRel.getDescPlayerOne();
|
||||
|
||||
mplayer.msg("<b>You can't use \"<h>/%s<b>\" as there is <h>%s<b> nearby.", command, desc);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ... if there is no relation here then there are no further checks ...
|
||||
if (factionAtRel == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> deniedCommands = MConf.get().denyCommandsTerritoryRelation.get(factionAtRel);
|
||||
if (deniedCommands == null) {
|
||||
return;
|
||||
}
|
||||
if (!MUtil.containsCommand(command, deniedCommands)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mplayer.msg("<b>You can't use \"<h>/%s<b>\" in %s territory.", command, Txt.getNicedEnum(factionAtRel));
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.massivecore.Couple;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.mixin.MixinMessage;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class EngineDenyTeleport extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineDenyTeleport i = new EngineDenyTeleport();
|
||||
|
||||
public static EngineDenyTeleport get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CAN COMBAT DAMAGE HAPPEN
|
||||
// -------------------------------------------- //
|
||||
|
||||
private enum TerritoryType {
|
||||
ENEMY,
|
||||
WILDERNESS,
|
||||
OWN,
|
||||
OTHER
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void canTeleportHappen(PlayerTeleportEvent event) {
|
||||
Entry<TeleportCause, TerritoryType> entry = shouldBeCancelled(event);
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
TeleportCause cause = entry.getKey();
|
||||
TerritoryType deny = entry.getValue();
|
||||
|
||||
String teleportDesc = Txt.getNicedEnum(cause);
|
||||
String denyDesc = "";
|
||||
if (deny == TerritoryType.ENEMY) {
|
||||
denyDesc = "enemy";
|
||||
}
|
||||
if (deny == TerritoryType.WILDERNESS) {
|
||||
denyDesc = "wilderness";
|
||||
}
|
||||
if (deny == TerritoryType.OWN) {
|
||||
denyDesc = "your own";
|
||||
}
|
||||
if (deny == TerritoryType.OTHER) {
|
||||
denyDesc = "other faction's";
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
MixinMessage.get().msgOne(player, "<b>Teleportation with %s is not allowed in %s territory.", teleportDesc, denyDesc);
|
||||
}
|
||||
|
||||
private Entry<TeleportCause, TerritoryType> shouldBeCancelled(PlayerTeleportEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (MUtil.isntPlayer(player)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MPlayer mplayer = MPlayer.get(player);
|
||||
|
||||
PS from = PS.valueOf(event.getFrom());
|
||||
PS to = PS.valueOf(event.getTo());
|
||||
|
||||
TerritoryType typeFrom = getTerritoryType(mplayer, from);
|
||||
TerritoryType typeTo = getTerritoryType(mplayer, to);
|
||||
List<TerritoryType> types = MUtil.list(typeFrom, typeTo);
|
||||
|
||||
TeleportCause cause = event.getCause();
|
||||
MConf mconf = MConf.get();
|
||||
|
||||
if (cause == TeleportCause.CHORUS_FRUIT) {
|
||||
if (!mconf.allowChorusFruitInEnemyTerritory && types.contains(TerritoryType.ENEMY)) {
|
||||
return Couple.valueOf(cause, TerritoryType.ENEMY);
|
||||
}
|
||||
|
||||
if (!mconf.allowChorusFruitInWildernessTerritory && types.contains(TerritoryType.WILDERNESS)) {
|
||||
return Couple.valueOf(cause, TerritoryType.WILDERNESS);
|
||||
}
|
||||
|
||||
if (!mconf.allowChorusFruitInOwnTerritory && types.contains(TerritoryType.OWN)) {
|
||||
return Couple.valueOf(cause, TerritoryType.OWN);
|
||||
}
|
||||
|
||||
if (!mconf.allowChorusFruitInOtherTerritory && types.contains(TerritoryType.OTHER)) {
|
||||
return Couple.valueOf(cause, TerritoryType.OTHER);
|
||||
}
|
||||
} else if (cause == TeleportCause.ENDER_PEARL) {
|
||||
if (!mconf.allowEnderPearlInEnemyTerritory && types.contains(TerritoryType.ENEMY)) {
|
||||
return Couple.valueOf(cause, TerritoryType.ENEMY);
|
||||
}
|
||||
|
||||
if (!mconf.allowEnderPearlInWildernessTerritory && types.contains(TerritoryType.WILDERNESS)) {
|
||||
return Couple.valueOf(cause, TerritoryType.WILDERNESS);
|
||||
}
|
||||
|
||||
if (!mconf.allowEnderPearlInOwnTerritory && types.contains(TerritoryType.OWN)) {
|
||||
return Couple.valueOf(cause, TerritoryType.OWN);
|
||||
}
|
||||
|
||||
if (!mconf.allowEnderPearlInOtherTerritory && types.contains(TerritoryType.OTHER)) {
|
||||
return Couple.valueOf(cause, TerritoryType.OTHER);
|
||||
}
|
||||
} else {
|
||||
// Don't cancel other kinds of teleports
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private TerritoryType getTerritoryType(MPlayer mplayer, PS territory) {
|
||||
Faction territoryFaction = BoardColl.get().getFactionAt(territory);
|
||||
Rel relation = territoryFaction.getRelationTo(mplayer);
|
||||
|
||||
if (territoryFaction.isNone()) {
|
||||
return TerritoryType.WILDERNESS;
|
||||
}
|
||||
if (relation == Rel.ENEMY) {
|
||||
return TerritoryType.ENEMY;
|
||||
}
|
||||
if (relation == Rel.FACTION) {
|
||||
return TerritoryType.OWN;
|
||||
}
|
||||
return TerritoryType.OTHER;
|
||||
}
|
||||
|
||||
}
|
268
src/main/java/com/massivecraft/factions/engine/EngineEcon.java
Normal file
268
src/main/java/com/massivecraft/factions/engine/EngineEcon.java
Normal file
@ -0,0 +1,268 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.cmd.CmdFactions;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.factions.event.EventFactionsAbstractSender;
|
||||
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
|
||||
import com.massivecraft.factions.event.EventFactionsChunksChange;
|
||||
import com.massivecraft.factions.event.EventFactionsCreate;
|
||||
import com.massivecraft.factions.event.EventFactionsDescriptionChange;
|
||||
import com.massivecraft.factions.event.EventFactionsDisband;
|
||||
import com.massivecraft.factions.event.EventFactionsFlagChange;
|
||||
import com.massivecraft.factions.event.EventFactionsInvitedChange;
|
||||
import com.massivecraft.factions.event.EventFactionsMembershipChange;
|
||||
import com.massivecraft.factions.event.EventFactionsMembershipChange.MembershipChangeReason;
|
||||
import com.massivecraft.factions.event.EventFactionsNameChange;
|
||||
import com.massivecraft.factions.event.EventFactionsRelationChange;
|
||||
import com.massivecraft.factions.event.EventFactionsTitleChange;
|
||||
import com.massivecraft.factions.event.EventFactionsWarpAdd;
|
||||
import com.massivecraft.factions.event.EventFactionsWarpRemove;
|
||||
import com.massivecraft.factions.event.EventFactionsWarpTeleport;
|
||||
import com.massivecraft.factions.integration.Econ;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.money.Money;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
public class EngineEcon extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineEcon i = new EngineEcon();
|
||||
|
||||
public static EngineEcon get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// TAKE ON LEAVE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void takeOnLeave(EventFactionsMembershipChange event) {
|
||||
if (!Econ.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If a player is leaving the faction ...
|
||||
if (event.getReason() != MembershipChangeReason.LEAVE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and that player was the last one in the faction ...
|
||||
MPlayer mplayer = event.getMPlayer();
|
||||
Faction oldFaction = mplayer.getFaction();
|
||||
if (oldFaction.getMPlayers().size() > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... then transfer all money to the player.
|
||||
double money = Econ.getMoney(oldFaction);
|
||||
if (money == 0) {
|
||||
return;
|
||||
}
|
||||
Econ.transferMoney(mplayer, oldFaction, mplayer, money);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// TAKE ON DISBAND
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void takeOnDisband(EventFactionsDisband event) {
|
||||
// If there is a mplayer ...
|
||||
MPlayer mplayer = event.getMPlayer();
|
||||
if (mplayer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and economy is enabled ...
|
||||
if (!Econ.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... then transfer all the faction money to the sender.
|
||||
Faction faction = event.getFaction();
|
||||
|
||||
double amount = Econ.getMoney(faction);
|
||||
|
||||
// Check that there is an amount
|
||||
if (amount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
String amountString = Money.format(amount);
|
||||
|
||||
Econ.transferMoney(faction, mplayer, mplayer, amount, true);
|
||||
|
||||
mplayer.msg("<i>You have been given the disbanded faction's bank, totaling %s.", amountString);
|
||||
Factions.get().log(mplayer.getName() + " has been given bank holdings of " + amountString + " from disbanding " + faction.getName() + ".");
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// PAY FOR ACTION
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static void payForAction(EventFactionsAbstractSender event, Double cost, String desc) {
|
||||
// If there is an mplayer ...
|
||||
MPlayer mplayer = event.getMPlayer();
|
||||
if (mplayer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and there is a cost ...
|
||||
if (cost == null) {
|
||||
return;
|
||||
}
|
||||
if (cost == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... that the sender can't afford ...
|
||||
if (Econ.payForAction(cost, mplayer, desc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... then cancel.
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForAction(EventFactionsChunksChange event) {
|
||||
double cost = 0;
|
||||
List<String> typeNames = new ArrayList<>();
|
||||
|
||||
for (Entry<EventFactionsChunkChangeType, Set<PS>> typeChunks : event.getTypeChunks().entrySet()) {
|
||||
final EventFactionsChunkChangeType type = typeChunks.getKey();
|
||||
final Set<PS> chunks = typeChunks.getValue();
|
||||
|
||||
Double typeCost = MConf.get().econChunkCost.get(type);
|
||||
if (typeCost == null) {
|
||||
continue;
|
||||
}
|
||||
if (typeCost == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
typeCost *= chunks.size();
|
||||
cost += typeCost;
|
||||
|
||||
typeNames.add(type.now);
|
||||
}
|
||||
|
||||
String desc = Txt.implodeCommaAnd(typeNames) + " this land";
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForAction(EventFactionsMembershipChange event) {
|
||||
Double cost = null;
|
||||
String desc = null;
|
||||
|
||||
if (event.getReason() == MembershipChangeReason.JOIN) {
|
||||
cost = MConf.get().econCostJoin;
|
||||
desc = "join a faction";
|
||||
} else if (event.getReason() == MembershipChangeReason.LEAVE) {
|
||||
cost = MConf.get().econCostLeave;
|
||||
desc = "leave a faction";
|
||||
} else if (event.getReason() == MembershipChangeReason.KICK) {
|
||||
cost = MConf.get().econCostKick;
|
||||
desc = "kick someone from a faction";
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForCommand(EventFactionsRelationChange event) {
|
||||
Double cost = MConf.get().econRelCost.get(event.getNewRelation());
|
||||
String desc = CmdFactions.get().cmdFactionsRelation.cmdFactionsRelationSet.getDesc();
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForCommand(EventFactionsWarpAdd event) {
|
||||
Double cost = MConf.get().econCostWarpAdd;
|
||||
String desc = CmdFactions.get().cmdFactionsWarp.cmdFactionWarpAdd.getDesc();
|
||||
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForCommand(EventFactionsWarpRemove event) {
|
||||
Double cost = MConf.get().econCostWarpRemove;
|
||||
String desc = CmdFactions.get().cmdFactionsWarp.cmdFactionWarpRemove.getDesc();
|
||||
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForCommand(EventFactionsCreate event) {
|
||||
Double cost = MConf.get().econCostCreate;
|
||||
String desc = CmdFactions.get().cmdFactionsCreate.getDesc();
|
||||
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForCommand(EventFactionsDescriptionChange event) {
|
||||
Double cost = MConf.get().econCostDescription;
|
||||
String desc = CmdFactions.get().cmdFactionsDescription.getDesc();
|
||||
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForCommand(EventFactionsNameChange event) {
|
||||
Double cost = MConf.get().econCostName;
|
||||
String desc = CmdFactions.get().cmdFactionsName.getDesc();
|
||||
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForCommand(EventFactionsTitleChange event) {
|
||||
Double cost = MConf.get().econCostTitle;
|
||||
String desc = CmdFactions.get().cmdFactionsTitle.getDesc();
|
||||
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForCommand(EventFactionsFlagChange event) {
|
||||
Double cost = MConf.get().econCostFlag;
|
||||
String desc = CmdFactions.get().cmdFactionsFlag.getDesc();
|
||||
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForCommand(EventFactionsInvitedChange event) {
|
||||
Double cost = event.isNewInvited() ? MConf.get().econCostInvite : MConf.get().econCostDeinvite;
|
||||
String desc = CmdFactions.get().cmdFactionsInvite.getDesc();
|
||||
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void payForCommand(EventFactionsWarpTeleport event) {
|
||||
Double cost = MConf.get().econCostWarpGo;
|
||||
String desc = CmdFactions.get().cmdFactionsWarp.cmdFactionsWarpGo.getDesc();
|
||||
|
||||
payForAction(event, cost, desc);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,226 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.collections.MassiveList;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class EngineExploit extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineExploit i = new EngineExploit();
|
||||
|
||||
public static EngineExploit get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OBSIDIAN GENERATORS
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void obsidianGenerators(BlockFromToEvent event) {
|
||||
if (!MConf.get().handleExploitObsidianGenerators) {
|
||||
return;
|
||||
}
|
||||
|
||||
// thanks to ObGenBlocker and WorldGuard for this method
|
||||
Block block = event.getToBlock();
|
||||
Material source = event.getBlock().getType();
|
||||
Material target = block.getType();
|
||||
if ((target == Material.REDSTONE_WIRE || target == Material.TRIPWIRE) && (source == Material.AIR || source == Material.LAVA)) {
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// ENDER PEARL CLIPPING
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void enderPearlClipping(PlayerTeleportEvent event) {
|
||||
if (!MConf.get().handleExploitEnderPearlClipping) {
|
||||
return;
|
||||
}
|
||||
if (event.getCause() != PlayerTeleportEvent.TeleportCause.ENDER_PEARL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this exploit works when the target location is within 0.31 blocks or so of a door or glass block or similar...
|
||||
Location target = event.getTo();
|
||||
Location from = event.getFrom();
|
||||
|
||||
// blocks who occupy less than 1 block width or length wise need to be handled differently
|
||||
Material mat = event.getTo().getBlock().getType();
|
||||
if (
|
||||
((mat == Material.GLASS_PANE || mat == Material.IRON_BARS) && clippingThrough(target, from, 0.65))
|
||||
|| ((MUtil.list(Material.ACACIA_FENCE, Material.BIRCH_FENCE, Material.DARK_OAK_FENCE, Material.JUNGLE_FENCE, Material.NETHER_BRICK_FENCE, Material.OAK_FENCE, Material.SPRUCE_FENCE).contains(mat)) && clippingThrough(target, from, 0.45))
|
||||
) {
|
||||
event.setTo(from);
|
||||
return;
|
||||
}
|
||||
|
||||
// simple fix otherwise: ender pearl target locations are standardized to be in the center (X/Z) of the target block, not at the edges
|
||||
target.setX(target.getBlockX() + 0.5);
|
||||
target.setZ(target.getBlockZ() + 0.5);
|
||||
event.setTo(target);
|
||||
|
||||
}
|
||||
|
||||
public static boolean clippingThrough(Location target, Location from, double thickness) {
|
||||
return
|
||||
(
|
||||
(from.getX() > target.getX() && (from.getX() - target.getX() < thickness))
|
||||
|| (target.getX() > from.getX() && (target.getX() - from.getX() < thickness))
|
||||
|| (from.getZ() > target.getZ() && (from.getZ() - target.getZ() < thickness))
|
||||
|| (target.getZ() > from.getZ() && (target.getZ() - from.getZ() < thickness))
|
||||
);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// NETHER PORTAL TRAP
|
||||
// -------------------------------------------- //
|
||||
// A nether portal trap can be created by the destination portal being enclosed (trapped) - resulting in the player not being able to run commands.
|
||||
// This fix removes the portal blocks (client side) from the destination until they are away from the portal.
|
||||
|
||||
private static final int NETHER_TRAP_RADIUS_CHECK = 5;
|
||||
private static final int NETHER_TRAP_RESET_RADIUS_SQUARED = 9;
|
||||
|
||||
private HashMap<UUID, List<Block>> portalTraps = new HashMap<>();
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void portalTrapRemoveAnimation(PlayerTeleportEvent event) {
|
||||
// If there is a teleport caused by a nether portal ...
|
||||
if (!MConf.get().handleNetherPortalTrap || event.getCause() != TeleportCause.NETHER_PORTAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
Block from = event.getTo().getBlock();
|
||||
|
||||
// ... and the player can't build at the destination ...
|
||||
if (EnginePermBuild.canPlayerBuildAt(player, PS.valueOf(from), false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... reset the old portal blocks stored ...
|
||||
this.portalReset(player);
|
||||
|
||||
// ... get all the portal blocks belonging to the new portal at the destination ...
|
||||
List<Block> portalTrap = getPortal(from);
|
||||
if (portalTrap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and then store those blocks and send an update as if they were air.
|
||||
this.portalTraps.put(player.getUniqueId(), portalTrap);
|
||||
portalUpdateAir(player, portalTrap);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void portalUpdate(PlayerMoveEvent event) {
|
||||
// If a player moves ...
|
||||
if (!MConf.get().handleNetherPortalTrap || MUtil.isSameBlock(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
UUID uuid = player.getUniqueId();
|
||||
|
||||
// ... and he recently used a portal ...
|
||||
List<Block> portalTrap = this.portalTraps.get(uuid);
|
||||
if (portalTrap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Location locationTo = event.getTo();
|
||||
Location locationFrom = portalTrap.get(0).getLocation();
|
||||
|
||||
World worldTo = locationTo.getWorld();
|
||||
World worldFrom = locationFrom.getWorld();
|
||||
|
||||
// ... update reset the portal near them, if they have moved away too far ...
|
||||
if (!worldTo.equals(worldFrom) || locationTo.distanceSquared(locationFrom) > NETHER_TRAP_RESET_RADIUS_SQUARED) {
|
||||
portalUpdateReset(player, portalTrap);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... or send an update as if the portal blocks were air.
|
||||
portalUpdateAir(player, portalTrap);
|
||||
}
|
||||
|
||||
public void portalReset(Player player) {
|
||||
UUID uuid = player.getUniqueId();
|
||||
|
||||
// If a player has already a portal registered to him ...
|
||||
List<Block> portalTrap = this.portalTraps.get(uuid);
|
||||
if (portalTrap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... remove them from the registry ...
|
||||
this.portalTraps.remove(uuid);
|
||||
|
||||
// ... and send updates if the player and portal are in the same world.
|
||||
if (!player.getWorld().equals(portalTrap.get(0).getWorld())) {
|
||||
return;
|
||||
}
|
||||
portalUpdateReset(player, portalTrap);
|
||||
}
|
||||
|
||||
public static void portalUpdateReset(Player player, List<Block> portal) {
|
||||
portalUpdate(player, portal, null, null);
|
||||
}
|
||||
|
||||
public static void portalUpdateAir(Player player, List<Block> portal) {
|
||||
portalUpdate(player, portal, Material.AIR, (byte) 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void portalUpdate(Player player, List<Block> portal, Material material, Byte data) {
|
||||
boolean usingDefault = material == null && data == null;
|
||||
for (Block block : portal) {
|
||||
Material updateMaterial = usingDefault ? block.getType() : material;
|
||||
byte updateData = usingDefault ? block.getData() : data;
|
||||
player.sendBlockChange(block.getLocation(), updateMaterial, updateData);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Block> getPortal(Block from) {
|
||||
// Create
|
||||
List<Block> ret = new MassiveList<>();
|
||||
|
||||
// Fill - Check in a radius of the block to find the portal blocks
|
||||
for (int x = -(NETHER_TRAP_RADIUS_CHECK); x <= NETHER_TRAP_RADIUS_CHECK; x++) {
|
||||
for (int y = -(NETHER_TRAP_RADIUS_CHECK); y <= NETHER_TRAP_RADIUS_CHECK; y++) {
|
||||
for (int z = -(NETHER_TRAP_RADIUS_CHECK); z <= NETHER_TRAP_RADIUS_CHECK; z++) {
|
||||
if (from.getRelative(x, y, z).getType() == Material.NETHER_PORTAL) {
|
||||
ret.add(from.getRelative(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MFlag;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import org.bukkit.entity.Enderman;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
|
||||
public class EngineFlagEndergrief extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineFlagEndergrief i = new EngineFlagEndergrief();
|
||||
|
||||
public static EngineFlagEndergrief get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// 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());
|
||||
Faction faction = BoardColl.get().getFactionAt(ps);
|
||||
if (faction.getFlag(MFlag.getFlagEndergrief())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... stop the block alteration.
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.util.EnumerationUtil;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Wither;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakEvent.RemoveCause;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class EngineFlagExplosion extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineFlagExplosion i = new EngineFlagExplosion();
|
||||
|
||||
public static EngineFlagExplosion get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FLAG: EXPLOSIONS
|
||||
// -------------------------------------------- //
|
||||
|
||||
protected Set<DamageCause> DAMAGE_CAUSE_EXPLOSIONS = EnumSet.of(DamageCause.BLOCK_EXPLOSION, DamageCause.ENTITY_EXPLOSION);
|
||||
|
||||
@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;
|
||||
}
|
||||
Entity entity = event.getEntity();
|
||||
|
||||
// ... and the faction there has explosions disabled ...
|
||||
Faction faction = BoardColl.get().getFactionAt(PS.valueOf(entity.getLocation()));
|
||||
if (faction.isExplosionsAllowed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... then cancel.
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void blockExplosion(EntityDamageEvent event) {
|
||||
// If an explosion damages ...
|
||||
if (!DAMAGE_CAUSE_EXPLOSIONS.contains(event.getCause())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... an entity that is modified on damage ...
|
||||
if (!EnumerationUtil.isEntityTypeEditOnDamage(event.getEntityType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and the faction has explosions disabled ...
|
||||
if (BoardColl.get().getFactionAt(PS.valueOf(event.getEntity())).isExplosionsAllowed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... then cancel!
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void blockExplosion(EntityExplodeEvent event) {
|
||||
Location location = event.getLocation();
|
||||
Cancellable cancellable = event;
|
||||
Collection<Block> blocks = event.blockList();
|
||||
|
||||
blockExplosion(location, cancellable, blocks);
|
||||
}
|
||||
|
||||
// Note that this method is used by EngineV18 for the BlockExplodeEvent
|
||||
public void blockExplosion(Location location, Cancellable cancellable, Collection<Block> blocks) {
|
||||
// Caching to speed things up.
|
||||
Map<Faction, Boolean> faction2allowed = new HashMap<>();
|
||||
|
||||
// Check the entity. Are explosions disabled there?
|
||||
Faction faction = BoardColl.get().getFactionAt(PS.valueOf(location));
|
||||
Boolean allowed = faction.isExplosionsAllowed();
|
||||
if (!allowed) {
|
||||
cancellable.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
faction2allowed.put(faction, allowed);
|
||||
|
||||
// Individually check the flag state for each block
|
||||
Iterator<Block> iterator = blocks.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Block block = iterator.next();
|
||||
faction = BoardColl.get().getFactionAt(PS.valueOf(block));
|
||||
allowed = faction2allowed.get(faction);
|
||||
if (allowed == null) {
|
||||
allowed = faction.isExplosionsAllowed();
|
||||
faction2allowed.put(faction, allowed);
|
||||
}
|
||||
|
||||
if (!allowed) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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());
|
||||
Faction faction = BoardColl.get().getFactionAt(ps);
|
||||
|
||||
if (faction.isExplosionsAllowed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... stop the block alteration.
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void blockExplosion(BlockExplodeEvent event) {
|
||||
Location location = event.getBlock().getLocation();
|
||||
Cancellable cancellable = event;
|
||||
Collection<Block> blocks = event.blockList();
|
||||
|
||||
EngineFlagExplosion.get().blockExplosion(location, cancellable, blocks);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MFlag;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockBurnEvent;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
|
||||
import org.bukkit.event.block.BlockSpreadEvent;
|
||||
|
||||
public class EngineFlagFireSpread extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineFlagFireSpread i = new EngineFlagFireSpread();
|
||||
|
||||
public static EngineFlagFireSpread get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FLAG: FIRE SPREAD
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void blockFireSpread(Block block, Cancellable cancellable) {
|
||||
// If the faction at the block has firespread disabled ...
|
||||
PS ps = PS.valueOf(block);
|
||||
Faction faction = BoardColl.get().getFactionAt(ps);
|
||||
|
||||
if (faction.getFlag(MFlag.getFlagFirespread())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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 ...
|
||||
if (event.getNewState().getType() != Material.FIRE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... 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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MFlag;
|
||||
import com.massivecraft.factions.util.EnumerationUtil;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.collections.BackstringSet;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class EngineFlagSpawn extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineFlagSpawn i = new EngineFlagSpawn();
|
||||
|
||||
public static EngineFlagSpawn get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CONSTANTS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static final Set<SpawnReason> NATURAL_SPAWN_REASONS = new BackstringSet<>(SpawnReason.class,
|
||||
"NATURAL",
|
||||
"JOCKEY",
|
||||
"CHUNK_GEN",
|
||||
"OCELOT_BABY",
|
||||
"NETHER_PORTAL",
|
||||
"MOUNT",
|
||||
"REINFORCEMENTS",
|
||||
"VILLAGE_DEFENSE",
|
||||
"VILLAGE_INVASION",
|
||||
"RAID",
|
||||
"PATROL"
|
||||
);
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FLAG: MONSTERS & ANIMALS
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void blockMonstersAndAnimals(CreatureSpawnEvent event) {
|
||||
// If this is a natural spawn ..
|
||||
if (!NATURAL_SPAWN_REASONS.contains(event.getSpawnReason())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... get the spawn location ...
|
||||
Location location = event.getLocation();
|
||||
PS ps = PS.valueOf(location);
|
||||
|
||||
// ... get the faction there ...
|
||||
Faction faction = BoardColl.get().getFactionAt(ps);
|
||||
if (faction == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... get the entity type ...
|
||||
EntityType type = event.getEntityType();
|
||||
|
||||
// ... and if this type can't spawn in the faction ...
|
||||
if (canSpawn(faction, type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... then cancel.
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
public static boolean canSpawn(Faction faction, EntityType type) {
|
||||
if (EnumerationUtil.isEntityTypeMonster(type)) {
|
||||
// Monster
|
||||
return faction.getFlag(MFlag.getFlagMonsters());
|
||||
} else if (EnumerationUtil.isEntityTypeAnimal(type)) {
|
||||
// Animal
|
||||
return faction.getFlag(MFlag.getFlagAnimals());
|
||||
} else {
|
||||
// Other
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MFlag;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Zombie;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityBreakDoorEvent;
|
||||
|
||||
public class EngineFlagZombiegrief extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineFlagZombiegrief i = new EngineFlagZombiegrief();
|
||||
|
||||
public static EngineFlagZombiegrief get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FLAG: ZOMBIEGRIEF
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void denyZombieGrief(EntityBreakDoorEvent event) {
|
||||
// If a zombie is breaking a door ...
|
||||
Entity entity = event.getEntity();
|
||||
if (!(entity instanceof Zombie)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and the faction there has zombiegrief disabled ...
|
||||
PS ps = PS.valueOf(event.getBlock());
|
||||
Faction faction = BoardColl.get().getFactionAt(ps);
|
||||
if (faction.getFlag(MFlag.getFlagZombiegrief())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... stop the door breakage.
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
}
|
239
src/main/java/com/massivecraft/factions/engine/EngineFly.java
Normal file
239
src/main/java/com/massivecraft/factions/engine/EngineFly.java
Normal file
@ -0,0 +1,239 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.Perm;
|
||||
import com.massivecraft.factions.cmd.CmdFactions;
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MFlag;
|
||||
import com.massivecraft.factions.entity.MFlagColl;
|
||||
import com.massivecraft.factions.entity.MPerm;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.factions.event.EventFactionsFlagChange;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.MassiveException;
|
||||
import com.massivecraft.massivecore.event.EventMassiveCorePlayerUpdate;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.store.DriverFlatfile;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class EngineFly extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineFly i = new EngineFly();
|
||||
|
||||
public static EngineFly get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// LISTENER
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onMassiveCorePlayerUpdate(EventMassiveCorePlayerUpdate event) {
|
||||
// If we are updating a player ...
|
||||
Player player = event.getPlayer();
|
||||
if (MUtil.isntPlayer(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and that player isn't in creative or spectator mode ...
|
||||
if (EventMassiveCorePlayerUpdate.isFlyAllowed(player, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and the player is alive ...
|
||||
if (player.isDead()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MPlayer mplayer = MPlayer.get(player);
|
||||
|
||||
// ... and the player enables flying ...
|
||||
if (!mplayer.isFlying()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and the player can fly here...
|
||||
if (!canFlyInTerritory(mplayer, PS.valueOf(player))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... set allowed ...
|
||||
event.setAllowed(true);
|
||||
|
||||
// ... set speed ...
|
||||
event.setFlySpeed(MConf.get().flySpeed);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void moveChunkDetect(PlayerMoveEvent event) {
|
||||
// If the player is moving from one chunk to another ...
|
||||
if (MUtil.isSameChunk(event)) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
if (MUtil.isntPlayer(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... gather info on the player and the move ...
|
||||
MPlayer mplayer = MPlayer.get(player);
|
||||
PS chunkTo = PS.valueOf(event.getTo()).getChunk(true);
|
||||
|
||||
// ... and they are currently flying ...
|
||||
if (!mplayer.isFlying()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... but can't fly at the new place ...
|
||||
if (canFlyInTerritory(mplayer, chunkTo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... then perhaps they should not be
|
||||
mplayer.setFlying(false);
|
||||
deactivateForPlayer(player);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void flagUpdate(EventFactionsFlagChange event) {
|
||||
if (event.getFlag() != MFlag.getFlagFly()) {
|
||||
return;
|
||||
}
|
||||
if (event.isNewValue() == true) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable for all players when disabled
|
||||
event.getFaction().getOnlinePlayers().forEach(EngineFly::deactivateForPlayer);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void territoryShield(EntityDamageByEntityEvent event) {
|
||||
// If flying is diabled on PVP ...
|
||||
if (!MConf.get().flyDisableOnPvp) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and the defender is a player ...
|
||||
Entity entity = event.getEntity();
|
||||
if (MUtil.isntPlayer(entity)) {
|
||||
return;
|
||||
}
|
||||
Player defender = (Player) entity;
|
||||
MPlayer mdefender = MPlayer.get(defender);
|
||||
|
||||
// ... and the attacker is a player ...
|
||||
Entity eattacker = MUtil.getLiableDamager(event);
|
||||
if (!(eattacker instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
Player attacker = (Player) eattacker;
|
||||
MPlayer mattacker = MPlayer.get(attacker);
|
||||
|
||||
// ... disable flying for both
|
||||
if (mdefender.isFlying()) {
|
||||
mdefender.setFlying(false);
|
||||
deactivateForPlayer(defender);
|
||||
mdefender.msg("<i>Flying is disabled in combat.");
|
||||
}
|
||||
|
||||
if (mattacker.isFlying()) {
|
||||
mattacker.setFlying(false);
|
||||
deactivateForPlayer(attacker);
|
||||
mattacker.msg("<i>Flying is disabled in combat.");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean canFlyInTerritory(MPlayer mplayer, PS ps) {
|
||||
try {
|
||||
canFlyInTerritoryOrThrow(mplayer, ps);
|
||||
return true;
|
||||
} catch (MassiveException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void canFlyInTerritoryOrThrow(MPlayer mplayer, PS ps) throws MassiveException {
|
||||
if (!mplayer.isPlayer()) {
|
||||
throw new MassiveException().addMsg("<b>Only players can fly.");
|
||||
}
|
||||
|
||||
Faction faction = mplayer.getFaction();
|
||||
Faction locationFaction = BoardColl.get().getFactionAt(ps.getChunk(true));
|
||||
|
||||
if (faction != locationFaction) {
|
||||
throw new MassiveException().addMsg("<b>You can only fly within your own faction.");
|
||||
}
|
||||
|
||||
// If the faction does not have the flag ...
|
||||
if (!faction.getFlag(MFlag.getFlagFly())) {
|
||||
MFlag flag = MFlag.getFlagFly();
|
||||
MassiveException ex = new MassiveException()
|
||||
.addMsg("<b>Flying requires that the <h>%s <b>flag is enabled for your faction.", flag.getName());
|
||||
|
||||
// ... but they can change ...
|
||||
if (flag.isEditable()) {
|
||||
boolean canEdit = MPerm.getPermFlags().has(mplayer, faction, false);
|
||||
// ... and the player can edit it themselves ...
|
||||
if (canEdit) {
|
||||
// ... tell them to edit.
|
||||
ex.addMsg("<i>You can edit the flag with: ");
|
||||
ex.addMessage(CmdFactions.get().cmdFactionsFlag.cmdFactionsFlagSet.getTemplate(false, true, mplayer.getSender()));
|
||||
}
|
||||
// ... otherwise ...
|
||||
else {
|
||||
// .. tell them to have someone else edit it ...
|
||||
ex.addMsg("<i>You can ask a faction admin to change the flag.");
|
||||
}
|
||||
}
|
||||
// ... or only server admins can change it ...
|
||||
else {
|
||||
boolean isAdmin = Perm.OVERRIDE.has(mplayer.getSender());
|
||||
boolean isDefault = flag.isDefault();
|
||||
if (isAdmin) {
|
||||
boolean overriding = mplayer.isOverriding();
|
||||
ex.addMsg("<i>You can change the flag if you are overriding.");
|
||||
if (overriding) {
|
||||
ex.addMsg("<i>You are already overriding.");
|
||||
} else {
|
||||
ex.addMsg("<i>You can enable override with:");
|
||||
ex.addMessage(CmdFactions.get().cmdFactionsOverride.getTemplate(false, true, mplayer.getSender()));
|
||||
}
|
||||
|
||||
if (!isDefault) {
|
||||
ex.addMsg("<i>You can also ask someone with access to the configuration files to make flying enabled by default.");
|
||||
if (MFlagColl.get().getDb().getDriver() instanceof DriverFlatfile) {
|
||||
File file = DriverFlatfile.getDirectory(MFlagColl.get());
|
||||
ex.addMsg("<i>Configuring the flags can be done by editing the files in <h>%s<i>.", file.getAbsoluteFile());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ex.addMsg("<b>Only server admins can change the flag. Per default flying is %s.", isDefault ? "enabled" : "disabled");
|
||||
}
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public static void deactivateForPlayer(Player player) {
|
||||
EventMassiveCorePlayerUpdate.resetFlyAllowed(player);
|
||||
EventMassiveCorePlayerUpdate.resetFlyActive(player);
|
||||
EventMassiveCorePlayerUpdate.resetFlySpeed(player);
|
||||
|
||||
EventMassiveCorePlayerUpdate.run(player);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.event.EventMassiveCorePlayerLeave;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class EngineLastActivity extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineLastActivity i = new EngineLastActivity();
|
||||
|
||||
public static EngineLastActivity get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UPDATE LAST ACTIVITY
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static void updateLastActivity(CommandSender sender) {
|
||||
if (sender == null) {
|
||||
throw new RuntimeException("sender");
|
||||
}
|
||||
if (MUtil.isntSender(sender)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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(), () -> 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());
|
||||
}
|
||||
|
||||
}
|
105
src/main/java/com/massivecraft/factions/engine/EngineMotd.java
Normal file
105
src/main/java/com/massivecraft/factions/engine/EngineMotd.java
Normal file
@ -0,0 +1,105 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.mixin.MixinActual;
|
||||
import com.massivecraft.massivecore.mixin.MixinMessage;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EngineMotd extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineMotd i = new EngineMotd();
|
||||
|
||||
public static EngineMotd get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// MOTD
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static void motd(PlayerJoinEvent event, EventPriority currentPriority) {
|
||||
// Gather info ...
|
||||
final Player player = event.getPlayer();
|
||||
if (MUtil.isntPlayer(player)) {
|
||||
return;
|
||||
}
|
||||
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 (!MixinActual.get().isActualJoin(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... then prepare the messages ...
|
||||
final List<Object> messages = faction.getMotdMessages();
|
||||
|
||||
// ... and send to the player.
|
||||
if (MConf.get().motdDelayTicks < 0) {
|
||||
MixinMessage.get().messageOne(player, messages);
|
||||
} else {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Factions.get(), () -> MixinMessage.get().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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.AccessStatus;
|
||||
import com.massivecraft.factions.TerritoryAccess;
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.factions.util.AsciiMap;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.mixin.MixinTitle;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class EngineMoveChunk extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineMoveChunk i = new EngineMoveChunk();
|
||||
|
||||
public static EngineMoveChunk get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// MOVE CHUNK: DETECT
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void moveChunkDetect(PlayerMoveEvent event) {
|
||||
// If the player is moving from one chunk to another ...
|
||||
if (MUtil.isSameChunk(event)) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
if (MUtil.isntPlayer(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... gather info on the player and the move ...
|
||||
MPlayer mplayer = MPlayer.get(player);
|
||||
|
||||
PS psFrom = PS.valueOf(event.getFrom());
|
||||
PS psTo = PS.valueOf(event.getTo());
|
||||
|
||||
// ... send info onwards and try auto-claiming.
|
||||
sendChunkInfo(mplayer, player, psFrom, psTo);
|
||||
tryAutoClaim(mplayer, psTo);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// MOVE CHUNK: SEND CHUNK INFO
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static void sendChunkInfo(MPlayer mplayer, Player player, PS psFrom, PS psTo) {
|
||||
sendAutoMapUpdate(mplayer, psTo);
|
||||
sendFactionTerritoryInfo(mplayer, player, psFrom, psTo);
|
||||
sendTerritoryAccessMessage(mplayer, psFrom, psTo);
|
||||
}
|
||||
|
||||
private static void sendAutoMapUpdate(MPlayer mplayer, PS ps) {
|
||||
if (!mplayer.isMapAutoUpdating()) {
|
||||
return;
|
||||
}
|
||||
AsciiMap map = new AsciiMap(mplayer, ps, false);
|
||||
mplayer.message(map.render());
|
||||
}
|
||||
|
||||
private static void sendFactionTerritoryInfo(MPlayer mplayer, Player player, PS psFrom, PS psTo) {
|
||||
Faction factionFrom = BoardColl.get().getFactionAt(psFrom);
|
||||
Faction factionTo = BoardColl.get().getFactionAt(psTo);
|
||||
|
||||
if (factionFrom == factionTo) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mplayer.isTerritoryInfoTitles()) {
|
||||
String titleMain = parseTerritoryInfo(MConf.get().territoryInfoTitlesMain, mplayer, factionTo);
|
||||
String titleSub = parseTerritoryInfo(MConf.get().territoryInfoTitlesSub, mplayer, factionTo);
|
||||
int ticksIn = MConf.get().territoryInfoTitlesTicksIn;
|
||||
int ticksStay = MConf.get().territoryInfoTitlesTicksStay;
|
||||
int ticksOut = MConf.get().territoryInfoTitleTicksOut;
|
||||
MixinTitle.get().sendTitleMessage(player, ticksIn, ticksStay, ticksOut, titleMain, titleSub);
|
||||
} else {
|
||||
String message = parseTerritoryInfo(MConf.get().territoryInfoChat, mplayer, factionTo);
|
||||
player.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static String parseTerritoryInfo(String string, MPlayer mplayer, Faction faction) {
|
||||
if (string == null) {
|
||||
throw new NullPointerException("string");
|
||||
}
|
||||
if (faction == null) {
|
||||
throw new NullPointerException("faction");
|
||||
}
|
||||
|
||||
string = Txt.parse(string);
|
||||
string = string.replace("{name}", faction.getName());
|
||||
string = string.replace("{relcolor}", faction.getColorTo(mplayer).toString());
|
||||
string = string.replace("{desc}", faction.getDescriptionDesc());
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
private static void sendTerritoryAccessMessage(MPlayer mplayer, PS psFrom, PS psTo) {
|
||||
if (!MConf.get().territoryAccessShowMessage) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get TerritoryAccess for from & to chunks
|
||||
TerritoryAccess accessFrom = BoardColl.get().getTerritoryAccessAt(psFrom);
|
||||
TerritoryAccess accessTo = BoardColl.get().getTerritoryAccessAt(psTo);
|
||||
|
||||
// See if the status has changed
|
||||
AccessStatus statusFrom = accessFrom.getTerritoryAccess(mplayer);
|
||||
AccessStatus statusTo = accessTo.getTerritoryAccess(mplayer);
|
||||
if (statusFrom == statusTo) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Inform
|
||||
mplayer.message(statusTo.getStatusMessage());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// MOVE CHUNK: TRY AUTO CLAIM
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static void tryAutoClaim(MPlayer mplayer, PS chunkTo) {
|
||||
// If the player is auto claiming ...
|
||||
Faction autoClaimFaction = mplayer.getAutoClaimFaction();
|
||||
if (autoClaimFaction == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... try claim.
|
||||
mplayer.tryClaim(autoClaimFaction, Collections.singletonList(chunkTo));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,506 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.TerritoryAccess;
|
||||
import com.massivecraft.factions.entity.Board;
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.FactionColl;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MPerm;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.factions.util.EnumerationUtil;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
||||
import org.bukkit.event.block.BlockPistonRetractEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
||||
import org.bukkit.event.hanging.HangingPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
||||
import org.bukkit.event.player.PlayerBucketFillEvent;
|
||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class EnginePermBuild extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EnginePermBuild i = new EnginePermBuild();
|
||||
|
||||
public static EnginePermBuild get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// LOGIC > PROTECT
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static Boolean isProtected(ProtectCase protectCase, boolean verboose, MPlayer mplayer, PS ps, Object object) {
|
||||
if (mplayer == null) {
|
||||
return null;
|
||||
}
|
||||
if (protectCase == null) {
|
||||
return null;
|
||||
}
|
||||
String name = mplayer.getName();
|
||||
if (MConf.get().playersWhoBypassAllProtection.contains(name)) {
|
||||
return false;
|
||||
}
|
||||
if (mplayer.isOverriding()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MPerm perm = protectCase.getPerm(object);
|
||||
if (perm == null) {
|
||||
return null;
|
||||
}
|
||||
if (protectCase != ProtectCase.BUILD) {
|
||||
return !perm.has(mplayer, ps, verboose);
|
||||
}
|
||||
|
||||
if (!perm.has(mplayer, ps, false) && MPerm.getPermPainbuild().has(mplayer, ps, false)) {
|
||||
if (!verboose) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Faction hostFaction = BoardColl.get().getFactionAt(ps);
|
||||
mplayer.msg("<b>It is painful to build in the territory of %s<b>.", hostFaction.describeTo(mplayer));
|
||||
Player player = mplayer.getPlayer();
|
||||
if (player != null) {
|
||||
player.damage(MConf.get().actionDeniedPainAmount);
|
||||
}
|
||||
}
|
||||
|
||||
return !perm.has(mplayer, ps, verboose);
|
||||
}
|
||||
|
||||
public static Boolean protect(ProtectCase protectCase, boolean verboose, Player player, PS ps, Object object, Cancellable cancellable) {
|
||||
Boolean ret = isProtected(protectCase, verboose, MPlayer.get(player), ps, object);
|
||||
if (Boolean.TRUE.equals(ret) && cancellable != null) {
|
||||
cancellable.setCancelled(true);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Boolean build(Entity entity, Block block, Event event) {
|
||||
if (!(event instanceof Cancellable)) {
|
||||
return true;
|
||||
}
|
||||
if (MUtil.isntPlayer(entity)) {
|
||||
return false;
|
||||
}
|
||||
Player player = (Player) entity;
|
||||
boolean verboose = !isFake(event);
|
||||
return protect(ProtectCase.BUILD, verboose, player, PS.valueOf(block), block, (Cancellable) event);
|
||||
}
|
||||
|
||||
public static Boolean useItem(Player player, Block block, Material material, Cancellable cancellable) {
|
||||
return protect(ProtectCase.USE_ITEM, true, player, PS.valueOf(block), material, cancellable);
|
||||
}
|
||||
|
||||
public static Boolean useEntity(Player player, Entity entity, boolean verboose, Cancellable cancellable) {
|
||||
return protect(ProtectCase.USE_ENTITY, verboose, player, PS.valueOf(entity), entity, cancellable);
|
||||
}
|
||||
|
||||
public static Boolean useBlock(Player player, Block block, boolean verboose, Cancellable cancellable) {
|
||||
return protect(ProtectCase.USE_BLOCK, verboose, player, PS.valueOf(block), block.getType(), cancellable);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// LOGIC > PROTECT > BUILD
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static boolean canPlayerBuildAt(Object senderObject, PS ps, boolean verboose) {
|
||||
MPlayer mplayer = MPlayer.get(senderObject);
|
||||
if (mplayer == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Boolean ret = isProtected(ProtectCase.BUILD, verboose, mplayer, ps, null);
|
||||
return !Boolean.TRUE.equals(ret);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// BUILD > BLOCK
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void build(BlockPlaceEvent event) {
|
||||
build(event.getPlayer(), event.getBlock(), event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void build(BlockBreakEvent event) {
|
||||
build(event.getPlayer(), event.getBlock(), event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void build(SignChangeEvent event) {
|
||||
build(event.getPlayer(), event.getBlock(), event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void build(HangingPlaceEvent event) {
|
||||
build(event.getPlayer(), event.getBlock(), event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void build(HangingBreakByEntityEvent event) {
|
||||
build(event.getRemover(), event.getEntity().getLocation().getBlock(), event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void build(EntityChangeBlockEvent event) {
|
||||
// Handling lilypads being broken by boats
|
||||
Entity entity = event.getEntity();
|
||||
if (entity.getType() != EntityType.BOAT || entity.getPassengers().size() <= 0) {
|
||||
return;
|
||||
}
|
||||
Entity player = entity.getPassengers().stream().filter(MUtil::isPlayer).findAny().orElse(entity);
|
||||
|
||||
build(player, event.getBlock(), event);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------- //
|
||||
// USE > ITEM
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void useBlockItem(PlayerInteractEvent event) {
|
||||
// If the player right clicks (or is physical with) a block ...
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.PHYSICAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
Block block = event.getClickedBlock();
|
||||
Player player = event.getPlayer();
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and we are either allowed to use this block ...
|
||||
Boolean ret = useBlock(player, block, true, event);
|
||||
if (Boolean.TRUE.equals(ret)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... or are allowed to right click with the item, this event is safe to perform.
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
|
||||
return;
|
||||
}
|
||||
useItem(player, block, event.getMaterial(), event);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void useItem(PlayerBucketEmptyEvent event) {
|
||||
useItem(event.getPlayer(), event.getBlockClicked().getRelative(event.getBlockFace()), event.getBucket(), event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void useItem(PlayerBucketFillEvent event) {
|
||||
useItem(event.getPlayer(), event.getBlockClicked(), event.getBucket(), event);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// USE > ENTITY
|
||||
// -------------------------------------------- //
|
||||
|
||||
// This event will not fire for Minecraft 1.8 armor stands.
|
||||
// Armor stands are handled in EngineSpigot instead.
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void useEntity(PlayerInteractEntityEvent event) {
|
||||
// Ignore Off Hand
|
||||
if (isOffHand(event)) {
|
||||
return;
|
||||
}
|
||||
useEntity(event.getPlayer(), event.getRightClicked(), true, event);
|
||||
}
|
||||
|
||||
// This is a special Spigot event that fires for Minecraft 1.8 armor stands.
|
||||
// It also fires for other entity types but for those the event is buggy.
|
||||
// It seems we can only cancel interaction with armor stands from here.
|
||||
// Thus we only handle armor stands from here and handle everything else in EngineMain.
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void handleArmorStand(PlayerInteractAtEntityEvent event) {
|
||||
// Ignore Off Hand
|
||||
if (isOffHand(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Gather Info
|
||||
final Player player = event.getPlayer();
|
||||
if (MUtil.isntPlayer(player)) {
|
||||
return;
|
||||
}
|
||||
final Entity entity = event.getRightClicked();
|
||||
final boolean verboose = true;
|
||||
|
||||
// Only care for armor stands.
|
||||
if (entity.getType() != EntityType.ARMOR_STAND) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we can't use, block it
|
||||
EnginePermBuild.useEntity(player, entity, verboose, event);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// BUILD > ENTITY
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void buildEntity(EntityDamageByEntityEvent event) {
|
||||
// If a player ...
|
||||
Entity damager = MUtil.getLiableDamager(event);
|
||||
if (MUtil.isntPlayer(damager)) {
|
||||
return;
|
||||
}
|
||||
Player player = (Player) damager;
|
||||
|
||||
// ... damages an entity which is edited on damage ...
|
||||
Entity entity = event.getEntity();
|
||||
if (entity == null || !EnumerationUtil.isEntityTypeEditOnDamage(entity.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and the player can't build there, cancel the event
|
||||
build(player, entity.getLocation().getBlock(), event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void combustEntity(EntityCombustByEntityEvent event) {
|
||||
|
||||
// If a burning projectile ...
|
||||
if (!(event.getCombuster() instanceof Projectile)) {
|
||||
return;
|
||||
}
|
||||
Projectile entityProjectile = (Projectile) event.getCombuster();
|
||||
|
||||
// ... fired by a player ...
|
||||
ProjectileSource projectileSource = entityProjectile.getShooter();
|
||||
if (MUtil.isntPlayer(projectileSource)) {
|
||||
return;
|
||||
}
|
||||
Player player = (Player) projectileSource;
|
||||
|
||||
// ... and hits an entity which is edited on damage (and thus likely to burn) ...
|
||||
Entity entityTarget = event.getEntity();
|
||||
if (entityTarget == null || !EnumerationUtil.isEntityTypeEditOnDamage(entityTarget.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and the player can't build there, cancel the event
|
||||
Block block = entityTarget.getLocation().getBlock();
|
||||
protect(ProtectCase.BUILD, false, player, PS.valueOf(block), block, event);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// BUILD > PISTON
|
||||
// -------------------------------------------- //
|
||||
|
||||
/*
|
||||
* Note: With 1.8 and the slime blocks, retracting and extending pistons
|
||||
* became more of a problem. Blocks located on the border of a chunk
|
||||
* could have easily been stolen. That is the reason why every block
|
||||
* needs to be checked now, whether he moved into a territory which
|
||||
* he actually may not move into.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void blockBuild(BlockPistonExtendEvent event) {
|
||||
// Is checking deactivated by MConf?
|
||||
if (!MConf.get().handlePistonProtectionThroughDenyBuild) {
|
||||
return;
|
||||
}
|
||||
|
||||
Faction pistonFaction = BoardColl.get().getFactionAt(PS.valueOf(event.getBlock()));
|
||||
|
||||
List<Block> blocks = event.getBlocks();
|
||||
|
||||
// Check for all extended blocks
|
||||
for (Block block : blocks) {
|
||||
// Block which is being pushed into
|
||||
Block targetBlock = block.getRelative(event.getDirection());
|
||||
|
||||
// Members of a faction might not have build rights in their own territory, but pistons should still work regardless
|
||||
Faction targetFaction = BoardColl.get().getFactionAt(PS.valueOf(targetBlock));
|
||||
if (targetFaction == pistonFaction) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Perm check
|
||||
if (MPerm.getPermBuild().has(pistonFaction, targetFaction)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void blockBuild(BlockPistonRetractEvent event) {
|
||||
// Is checking deactivated by MConf?
|
||||
if (!MConf.get().handlePistonProtectionThroughDenyBuild) {
|
||||
return;
|
||||
}
|
||||
|
||||
Faction pistonFaction = BoardColl.get().getFactionAt(PS.valueOf(event.getBlock()));
|
||||
|
||||
List<Block> blocks = event.getBlocks();
|
||||
|
||||
// Check for all retracted blocks
|
||||
for (Block block : blocks) {
|
||||
// Is the retracted block air/water/lava? Don't worry about it
|
||||
if (block.isEmpty() || block.isLiquid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Members of a faction might not have build rights in their own territory, but pistons should still work regardless
|
||||
Faction targetFaction = BoardColl.get().getFactionAt(PS.valueOf(block));
|
||||
if (targetFaction == pistonFaction) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Perm check
|
||||
if (MPerm.getPermBuild().has(pistonFaction, targetFaction)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// BUILD > FIRE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void buildFire(PlayerInteractEvent event) {
|
||||
// If it is a left click on block and the clicked block is not null...
|
||||
if (event.getAction() != Action.LEFT_CLICK_BLOCK || event.getClickedBlock() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and the potential block is not null either ...
|
||||
Block potentialBlock = event.getClickedBlock().getRelative(BlockFace.UP, 1);
|
||||
if (potentialBlock == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Material blockType = potentialBlock.getType();
|
||||
|
||||
// ... and we're only going to check for fire ... (checking everything else would be bad performance wise)
|
||||
if (blockType != Material.FIRE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... check if they can't build, cancel the event ...
|
||||
if (!Boolean.FALSE.equals(build(event.getPlayer(), potentialBlock, event))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and compensate for client side prediction
|
||||
event.getPlayer().sendBlockChange(potentialBlock.getLocation(), blockType, potentialBlock.getState().getRawData());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// BUILD > MOVE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void buildMove(BlockFromToEvent event) {
|
||||
if (!MConf.get().protectionLiquidFlowEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare fields
|
||||
Block fromBlock = event.getBlock();
|
||||
int chunkFromX = fromBlock.getX() >> 4;
|
||||
int chunkFromZ = fromBlock.getZ() >> 4;
|
||||
BlockFace face = event.getFace();
|
||||
int chunkToX = (fromBlock.getX() + face.getModX()) >> 4;
|
||||
int chunkToZ = (fromBlock.getZ() + face.getModZ()) >> 4;
|
||||
|
||||
// If a liquid (or dragon egg) moves from one chunk to another ...
|
||||
if (chunkToX == chunkFromX && chunkToZ == chunkFromZ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... get the correct board for this block ...
|
||||
Board board = BoardColl.get().getFixed(fromBlock.getWorld().getName().toLowerCase(), false);
|
||||
if (board == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... get the access map ...
|
||||
Map<PS, TerritoryAccess> map = board.getMapRaw();
|
||||
if (map.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... get the faction ids from and to ...
|
||||
PS fromPs = PS.valueOf(chunkFromX, chunkFromZ);
|
||||
PS toPs = PS.valueOf(chunkToX, chunkToZ);
|
||||
TerritoryAccess fromTa = map.get(fromPs);
|
||||
TerritoryAccess toTa = map.get(toPs);
|
||||
|
||||
// Null checks are needed here since automatic board cleaning can be undesired sometimes
|
||||
String fromId = fromTa != null ? fromTa.getHostFactionId() : Factions.ID_NONE;
|
||||
String toId = toTa != null ? toTa.getHostFactionId() : Factions.ID_NONE;
|
||||
|
||||
// ... and the chunks belong to different factions ...
|
||||
if (toId.equals(fromId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and the faction "from" can not build at "to" ...
|
||||
Faction fromFac = FactionColl.get().getFixed(fromId);
|
||||
if (fromFac == null) {
|
||||
fromFac = FactionColl.get().getNone();
|
||||
}
|
||||
Faction toFac = FactionColl.get().getFixed(toId);
|
||||
if (toFac == null) {
|
||||
toFac = FactionColl.get().getNone();
|
||||
}
|
||||
if (MPerm.getPermBuild().has(fromFac, toFac)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... cancel the event!
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.factions.entity.MPlayerColl;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerKickEvent;
|
||||
|
||||
public class EnginePlayerData extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EnginePlayerData i = new EnginePlayerData();
|
||||
|
||||
public static EnginePlayerData get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// 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) ...
|
||||
//if (!event.getReason().equals("Banned by admin.")) return;
|
||||
if (!player.isBanned()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and we remove player data when banned ...
|
||||
if (!MConf.get().removePlayerWhenBanned) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... get rid of their stored info.
|
||||
MPlayer mplayer = MPlayerColl.get().get(player, false);
|
||||
if (mplayer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mplayer.getRank().isLeader()) {
|
||||
mplayer.getFaction().promoteNewLeader();
|
||||
}
|
||||
|
||||
mplayer.leave();
|
||||
mplayer.detach();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MFlag;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.factions.event.EventFactionsPowerChange;
|
||||
import com.massivecraft.factions.event.EventFactionsPowerChange.PowerChangeReason;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import com.massivecraft.massivecore.util.PlayerUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
|
||||
public class EnginePower extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EnginePower i = new EnginePower();
|
||||
|
||||
public static EnginePower get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// POWER LOSS ON DEATH
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void powerLossOnDeath(PlayerDeathEvent event) {
|
||||
// If a player dies ...
|
||||
Player player = event.getEntity();
|
||||
if (MUtil.isntPlayer(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... 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;
|
||||
}
|
||||
|
||||
MPlayer mplayer = MPlayer.get(player);
|
||||
|
||||
// ... and powerloss can happen here ...
|
||||
Faction faction = BoardColl.get().getFactionAt(PS.valueOf(player.getLocation()));
|
||||
|
||||
if (!faction.getFlag(MFlag.getFlagPowerloss())) {
|
||||
mplayer.msg("<i>You didn't lose any power since the territory you died in works that way.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MConf.get().worldsPowerLossEnabled.contains(player.getWorld())) {
|
||||
mplayer.msg("<i>You didn't lose any power due to the world you died in.");
|
||||
return;
|
||||
}
|
||||
|
||||
// ... alter the power ...
|
||||
double newPower = mplayer.getPower() + mplayer.getPowerPerDeath();
|
||||
|
||||
EventFactionsPowerChange powerChangeEvent = new EventFactionsPowerChange(null, mplayer, PowerChangeReason.DEATH, newPower);
|
||||
powerChangeEvent.run();
|
||||
if (powerChangeEvent.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
newPower = powerChangeEvent.getNewPower();
|
||||
|
||||
mplayer.setPower(newPower);
|
||||
|
||||
// ... and inform the player.
|
||||
// TODO: A progress bar here would be epic :)
|
||||
mplayer.msg("<i>Your power is now <h>%.2f / %.2f", newPower, mplayer.getPowerMax());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,192 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.event.EventMassiveCorePlayerLeave;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import com.massivecraft.massivecore.util.PeriodUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EngineSeeChunk extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineSeeChunk i = new EngineSeeChunk();
|
||||
|
||||
public static EngineSeeChunk get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
public EngineSeeChunk() {
|
||||
this.setPeriod(1L);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// LEAVE AND WORLD CHANGE REMOVAL
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static void leaveAndWorldChangeRemoval(Player player) {
|
||||
if (MUtil.isntPlayer(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final MPlayer mplayer = MPlayer.get(player);
|
||||
mplayer.setSeeingChunk(false);
|
||||
}
|
||||
|
||||
// Can't be cancelled
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void leaveAndWorldChangeRemoval(EventMassiveCorePlayerLeave event) {
|
||||
leaveAndWorldChangeRemoval(event.getPlayer());
|
||||
}
|
||||
|
||||
// Can't be cancelled
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void leaveAndWorldChangeRemoval(PlayerChangedWorldEvent event) {
|
||||
leaveAndWorldChangeRemoval(event.getPlayer());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// MODULO REPEAT TASK
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Do we have a new period?
|
||||
final long now = System.currentTimeMillis();
|
||||
final long length = 500;
|
||||
if (!PeriodUtil.isNewPeriod(this, length, now)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the period number
|
||||
final long period = PeriodUtil.getPeriod(length, now);
|
||||
|
||||
// Calculate the "step" from the period number
|
||||
final int steps = 1; // Example: 4
|
||||
final int step = (int) (period % steps); // Example: 0, 1, 2, 3
|
||||
|
||||
// Load other related config options
|
||||
final float offsetX = 0.0f;
|
||||
final float offsetY = 2;
|
||||
final float offsetZ = 0.0f;
|
||||
final float speed = 0;
|
||||
final int amount = 30;
|
||||
|
||||
// For each player
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
// Hide for dead players since the death screen looks better without.
|
||||
if (player.isDead()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// The player must obviously have the feature activated.
|
||||
MPlayer mplayer = MPlayer.get(player);
|
||||
if (!mplayer.isSeeingChunk()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate locations and play the effect there.
|
||||
List<Location> locations = getLocations(player, steps, step);
|
||||
for (Location location : locations) {
|
||||
location.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, location, amount, offsetX, offsetY, offsetZ, speed);
|
||||
//ParticleEffect.EXPLOSION_NORMAL.display(location, offsetX, offsetY, offsetZ, speed, amount, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Location> getLocations(Player player, int steps, int step) {
|
||||
// Clean Args
|
||||
if (player == null) {
|
||||
throw new NullPointerException("player");
|
||||
}
|
||||
if (steps < 1) {
|
||||
throw new InvalidParameterException("steps must be larger than 0");
|
||||
}
|
||||
if (step < 0) {
|
||||
throw new InvalidParameterException("step must at least be 0");
|
||||
}
|
||||
if (step >= steps) {
|
||||
throw new InvalidParameterException("step must be less than steps");
|
||||
}
|
||||
|
||||
// Create Ret
|
||||
List<Location> ret = new ArrayList<>();
|
||||
|
||||
final Location location = player.getLocation();
|
||||
final World world = location.getWorld();
|
||||
PS chunk = PS.valueOf(location).getChunk(true);
|
||||
|
||||
final int xmin = chunk.getChunkX() * 16;
|
||||
final int xmax = xmin + 15;
|
||||
final double y = location.getBlockY() + 2;
|
||||
final int zmin = chunk.getChunkZ() * 16;
|
||||
final int zmax = zmin + 15;
|
||||
|
||||
int keepEvery = 5;
|
||||
if (keepEvery <= 0) {
|
||||
keepEvery = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
int skipEvery = 0;
|
||||
if (skipEvery <= 0) {
|
||||
skipEvery = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
int x = xmin;
|
||||
int z = zmin;
|
||||
int i = 0;
|
||||
|
||||
// Add #1
|
||||
while (x + 1 <= xmax) {
|
||||
x++;
|
||||
i++;
|
||||
if (i % steps == step && (i % keepEvery == 0 && i % skipEvery != 0)) {
|
||||
ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
// Add #2
|
||||
while (z + 1 <= zmax) {
|
||||
z++;
|
||||
i++;
|
||||
if (i % steps == step && (i % keepEvery == 0 && i % skipEvery != 0)) {
|
||||
ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
// Add #3
|
||||
while (x - 1 >= xmin) {
|
||||
x--;
|
||||
i++;
|
||||
if (i % steps == step && (i % keepEvery == 0 && i % skipEvery != 0)) {
|
||||
ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
// Add #4
|
||||
while (z - 1 >= zmin) {
|
||||
z--;
|
||||
i++;
|
||||
if (i % steps == step && (i % keepEvery == 0 && i % skipEvery != 0)) {
|
||||
ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
// Return Ret
|
||||
return ret;
|
||||
}
|
||||
}
|
238
src/main/java/com/massivecraft/factions/engine/EngineShow.java
Normal file
238
src/main/java/com/massivecraft/factions/engine/EngineShow.java
Normal file
@ -0,0 +1,238 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.comparator.ComparatorMPlayerRole;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MFlag;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
|
||||
import com.massivecraft.factions.event.EventFactionsFactionShowAsync;
|
||||
import com.massivecraft.factions.integration.Econ;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.PriorityLines;
|
||||
import com.massivecraft.massivecore.money.Money;
|
||||
import com.massivecraft.massivecore.util.TimeDiffUtil;
|
||||
import com.massivecraft.massivecore.util.TimeUnit;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class EngineShow extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// CONSTANTS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static final String BASENAME = "factions";
|
||||
public static final String BASENAME_ = BASENAME + "_";
|
||||
|
||||
public static final String SHOW_ID_FACTION_ID = BASENAME_ + "id";
|
||||
public static final String SHOW_ID_FACTION_DESCRIPTION = BASENAME_ + "description";
|
||||
public static final String SHOW_ID_FACTION_AGE = BASENAME_ + "age";
|
||||
public static final String SHOW_ID_FACTION_FLAGS = BASENAME_ + "flags";
|
||||
public static final String SHOW_ID_FACTION_POWER = BASENAME_ + "power";
|
||||
public static final String SHOW_ID_FACTION_LANDVALUES = BASENAME_ + "landvalue";
|
||||
public static final String SHOW_ID_FACTION_BANK = BASENAME_ + "bank";
|
||||
public static final String SHOW_ID_FACTION_FOLLOWERS = BASENAME_ + "followers";
|
||||
|
||||
public static final int SHOW_PRIORITY_FACTION_ID = 1000;
|
||||
public static final int SHOW_PRIORITY_FACTION_DESCRIPTION = 2000;
|
||||
public static final int SHOW_PRIORITY_FACTION_AGE = 3000;
|
||||
public static final int SHOW_PRIORITY_FACTION_FLAGS = 4000;
|
||||
public static final int SHOW_PRIORITY_FACTION_POWER = 5000;
|
||||
public static final int SHOW_PRIORITY_FACTION_LANDVALUES = 6000;
|
||||
public static final int SHOW_PRIORITY_FACTION_BANK = 7000;
|
||||
public static final int SHOW_PRIORITY_FACTION_FOLLOWERS = 9000;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineShow i = new EngineShow();
|
||||
|
||||
public static EngineShow get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FACTION SHOW
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onFactionShow(EventFactionsFactionShowAsync event) {
|
||||
final int tableCols = 4;
|
||||
final CommandSender sender = event.getSender();
|
||||
final MPlayer mplayer = event.getMPlayer();
|
||||
final Faction faction = event.getFaction();
|
||||
final boolean normal = faction.isNormal();
|
||||
final Map<String, PriorityLines> idPriorityLiness = event.getIdPriorityLiness();
|
||||
String none = Txt.parse("<silver><italic>none");
|
||||
|
||||
// ID
|
||||
if (mplayer.isOverriding()) {
|
||||
show(idPriorityLiness, SHOW_ID_FACTION_ID, SHOW_PRIORITY_FACTION_ID, "ID", faction.getId());
|
||||
}
|
||||
|
||||
// DESCRIPTION
|
||||
show(idPriorityLiness, SHOW_ID_FACTION_DESCRIPTION, SHOW_PRIORITY_FACTION_DESCRIPTION, "Description", faction.getDescriptionDesc());
|
||||
|
||||
// SECTION: NORMAL
|
||||
if (normal) {
|
||||
// AGE
|
||||
long ageMillis = faction.getCreatedAtMillis() - System.currentTimeMillis();
|
||||
LinkedHashMap<TimeUnit, Long> ageUnitcounts = TimeDiffUtil.limit(TimeDiffUtil.unitcounts(ageMillis, TimeUnit.getAllButMillis()), 3);
|
||||
String ageDesc = TimeDiffUtil.formatedVerboose(ageUnitcounts, "<i>");
|
||||
show(idPriorityLiness, SHOW_ID_FACTION_AGE, SHOW_PRIORITY_FACTION_AGE, "Age", ageDesc);
|
||||
|
||||
// FLAGS
|
||||
// We display all editable and non default ones. The rest we skip.
|
||||
List<String> flagDescs = new LinkedList<>();
|
||||
for (Entry<MFlag, Boolean> entry : faction.getFlags().entrySet()) {
|
||||
final MFlag mflag = entry.getKey();
|
||||
if (mflag == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final Boolean value = entry.getValue();
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mflag.isInteresting(value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String flagDesc = Txt.parse(value ? "<g>" : "<b>") + mflag.getName();
|
||||
flagDescs.add(flagDesc);
|
||||
}
|
||||
String flagsDesc = Txt.parse("<silver><italic>default");
|
||||
if (!flagDescs.isEmpty()) {
|
||||
flagsDesc = Txt.implode(flagDescs, Txt.parse(" <i>| "));
|
||||
}
|
||||
show(idPriorityLiness, SHOW_ID_FACTION_FLAGS, SHOW_PRIORITY_FACTION_FLAGS, "Flags", flagsDesc);
|
||||
|
||||
// POWER
|
||||
double powerBoost = faction.getPowerBoost();
|
||||
String boost = (powerBoost == 0.0) ? "" : (powerBoost > 0.0 ? " (bonus: " : " (penalty: ") + powerBoost + ")";
|
||||
String powerDesc = Txt.parse("%d/%d/%d%s", faction.getLandCount(), faction.getPowerRounded(), faction.getPowerMaxRounded(), boost);
|
||||
show(idPriorityLiness, SHOW_ID_FACTION_POWER, SHOW_PRIORITY_FACTION_POWER, "Land / Power / Maxpower", powerDesc);
|
||||
|
||||
// SECTION: ECON
|
||||
if (Econ.isEnabled()) {
|
||||
// LANDVALUES
|
||||
List<String> landvalueLines = new LinkedList<>();
|
||||
long landCount = faction.getLandCount();
|
||||
for (EventFactionsChunkChangeType type : EventFactionsChunkChangeType.values()) {
|
||||
Double money = MConf.get().econChunkCost.get(type);
|
||||
if (money == null) {
|
||||
continue;
|
||||
}
|
||||
if (money == 0) {
|
||||
continue;
|
||||
}
|
||||
money *= landCount;
|
||||
|
||||
String word = "Cost";
|
||||
if (money <= 0) {
|
||||
word = "Reward";
|
||||
money *= -1;
|
||||
}
|
||||
|
||||
String key = Txt.parse("Total Land %s %s", type.toString().toLowerCase(), word);
|
||||
String value = Txt.parse("<h>%s", Money.format(money));
|
||||
String line = show(key, value);
|
||||
landvalueLines.add(line);
|
||||
}
|
||||
idPriorityLiness.put(SHOW_ID_FACTION_LANDVALUES, new PriorityLines(SHOW_PRIORITY_FACTION_LANDVALUES, landvalueLines));
|
||||
|
||||
// BANK
|
||||
if (MConf.get().bankEnabled) {
|
||||
double bank = Econ.getMoney(faction);
|
||||
String bankDesc = Txt.parse("<h>%s", Money.format(bank, true));
|
||||
show(idPriorityLiness, SHOW_ID_FACTION_BANK, SHOW_PRIORITY_FACTION_BANK, "Bank", bankDesc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FOLLOWERS
|
||||
List<String> followerLines = new ArrayList<>();
|
||||
|
||||
List<String> followerNamesOnline = new ArrayList<>();
|
||||
List<String> followerNamesOffline = new ArrayList<>();
|
||||
|
||||
List<MPlayer> followers = faction.getMPlayers();
|
||||
followers.sort(ComparatorMPlayerRole.get());
|
||||
for (MPlayer follower : followers) {
|
||||
if (follower.isOnline(sender)) {
|
||||
followerNamesOnline.add(follower.getNameAndTitle(mplayer));
|
||||
} else if (normal) {
|
||||
// For the non-faction we skip the offline members since they are far to many (infinite almost)
|
||||
followerNamesOffline.add(follower.getNameAndTitle(mplayer));
|
||||
}
|
||||
}
|
||||
|
||||
String headerOnline = Txt.parse("<a>Followers Online (%s):", followerNamesOnline.size());
|
||||
followerLines.add(headerOnline);
|
||||
if (followerNamesOnline.isEmpty()) {
|
||||
followerLines.add(none);
|
||||
} else {
|
||||
followerLines.addAll(table(followerNamesOnline, tableCols));
|
||||
}
|
||||
|
||||
if (normal) {
|
||||
String headerOffline = Txt.parse("<a>Followers Offline (%s):", followerNamesOffline.size());
|
||||
followerLines.add(headerOffline);
|
||||
if (followerNamesOffline.isEmpty()) {
|
||||
followerLines.add(none);
|
||||
} else {
|
||||
followerLines.addAll(table(followerNamesOffline, tableCols));
|
||||
}
|
||||
}
|
||||
idPriorityLiness.put(SHOW_ID_FACTION_FOLLOWERS, new PriorityLines(SHOW_PRIORITY_FACTION_FOLLOWERS, followerLines));
|
||||
}
|
||||
|
||||
public static String show(String key, String value) {
|
||||
return Txt.parse("<a>%s: <i>%s", key, value);
|
||||
}
|
||||
|
||||
public static PriorityLines show(int priority, String key, String value) {
|
||||
return new PriorityLines(priority, show(key, value));
|
||||
}
|
||||
|
||||
public static void show(Map<String, PriorityLines> idPriorityLiness, String id, int priority, String key, String value) {
|
||||
idPriorityLiness.put(id, show(priority, key, value));
|
||||
}
|
||||
|
||||
public static List<String> table(List<String> strings, int cols) {
|
||||
List<String> ret = new ArrayList<>();
|
||||
|
||||
StringBuilder row = new StringBuilder();
|
||||
int count = 0;
|
||||
|
||||
Iterator<String> iter = strings.iterator();
|
||||
while (iter.hasNext()) {
|
||||
String string = iter.next();
|
||||
row.append(string);
|
||||
count++;
|
||||
|
||||
if (iter.hasNext() && count != cols) {
|
||||
row.append(Txt.parse(" <i>| "));
|
||||
} else {
|
||||
ret.add(row.toString());
|
||||
row = new StringBuilder();
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.factions.entity.Warp;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EngineTeleportHomeOnDeath extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineTeleportHomeOnDeath i = new EngineTeleportHomeOnDeath();
|
||||
|
||||
public static EngineTeleportHomeOnDeath get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// TELEPORT TO HOME ON DEATH
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void teleportToHomeOnDeath(PlayerRespawnEvent event, EventPriority priority) {
|
||||
// If a player is respawning ...
|
||||
final Player player = event.getPlayer();
|
||||
if (MUtil.isntPlayer(player)) {
|
||||
return;
|
||||
}
|
||||
final MPlayer mplayer = MPlayer.get(player);
|
||||
|
||||
// ... homes are enabled, active and at this priority ...
|
||||
if (!MConf.get().warpsEnabled) {
|
||||
return;
|
||||
}
|
||||
if (!MConf.get().warpsTeleportToOnDeathActive) {
|
||||
return;
|
||||
}
|
||||
if (MConf.get().warpsTeleportToOnDeathPriority != priority) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and the player has a faction ...
|
||||
final Faction faction = mplayer.getFaction();
|
||||
if (faction.isNone()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and the faction has a home ...
|
||||
List<Warp> warps = faction.getWarps().getAll((java.util.function.Predicate<Warp>) (warp -> warp.getName().equalsIgnoreCase(MConf.get().warpsTeleportToOnDeathName)));
|
||||
if (warps.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Warp warp = warps.get(0);
|
||||
|
||||
// ... and the home is translatable ...
|
||||
Location respawnLocation = null;
|
||||
try {
|
||||
respawnLocation = warp.getLocation().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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.MPlayer;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
public class EngineTerritoryShield extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineTerritoryShield i = new EngineTerritoryShield();
|
||||
|
||||
public static EngineTerritoryShield get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// TERRITORY SHIELD
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void territoryShield(EntityDamageByEntityEvent event) {
|
||||
// If the entity is a player ...
|
||||
Entity entity = event.getEntity();
|
||||
if (MUtil.isntPlayer(entity)) {
|
||||
return;
|
||||
}
|
||||
Player player = (Player) entity;
|
||||
MPlayer mplayer = MPlayer.get(player);
|
||||
|
||||
// ... and the attacker is a player ...
|
||||
Entity attacker = MUtil.getLiableDamager(event);
|
||||
if (!(attacker instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and that player has a faction ...
|
||||
if (!mplayer.hasFaction()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and that player is in their own territory ...
|
||||
if (!mplayer.isInOwnTerritory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... and a territoryShieldFactor is configured ...
|
||||
if (MConf.get().territoryShieldFactor <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... then scale the damage ...
|
||||
double factor = 1D - MConf.get().territoryShieldFactor;
|
||||
MUtil.scaleDamage(event, factor);
|
||||
|
||||
// ... and inform.
|
||||
String perc = MessageFormat.format("{0,number,#%}", (MConf.get().territoryShieldFactor));
|
||||
mplayer.msg("<i>Enemy damage reduced by <rose>%s<i>.", perc);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.util.VisualizeUtil;
|
||||
import com.massivecraft.massivecore.Engine;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
|
||||
public class EngineVisualizations extends Engine {
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineVisualizations i = new EngineVisualizations();
|
||||
|
||||
public static EngineVisualizations get() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// VISUALIZE UTIL
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlayerMoveClearVisualizations(PlayerMoveEvent event) {
|
||||
if (MUtil.isSameBlock(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
VisualizeUtil.clear(event.getPlayer());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package com.massivecraft.factions.engine;
|
||||
|
||||
import com.massivecraft.factions.entity.MPerm;
|
||||
import com.massivecraft.factions.util.EnumerationUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public enum ProtectCase {
|
||||
// -------------------------------------------- //
|
||||
// ENUM
|
||||
// -------------------------------------------- //
|
||||
|
||||
BUILD,
|
||||
USE_BLOCK,
|
||||
USE_ITEM,
|
||||
USE_ENTITY,
|
||||
|
||||
// END OF LIST
|
||||
;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// PERM
|
||||
// -------------------------------------------- //
|
||||
|
||||
public MPerm getPerm(Object object) {
|
||||
switch (this) {
|
||||
case BUILD:
|
||||
return MPerm.getPermBuild();
|
||||
|
||||
case USE_ITEM:
|
||||
if (!(object instanceof Material)) {
|
||||
return null;
|
||||
}
|
||||
if (!EnumerationUtil.isMaterialEditTool((Material) object)) {
|
||||
return null;
|
||||
}
|
||||
return MPerm.getPermBuild();
|
||||
|
||||
case USE_ENTITY:
|
||||
if (!(object instanceof Entity)) {
|
||||
return null;
|
||||
}
|
||||
Entity entity = (Entity) object;
|
||||
EntityType type = entity.getType();
|
||||
if (EnumerationUtil.isEntityTypeContainer(type)) {
|
||||
return MPerm.getPermContainer();
|
||||
}
|
||||
if (EnumerationUtil.isEntityTypeEditOnInteract(type)) {
|
||||
return MPerm.getPermBuild();
|
||||
}
|
||||
|
||||
case USE_BLOCK:
|
||||
if (!(object instanceof Material)) {
|
||||
return null;
|
||||
}
|
||||
Material material = (Material) object;
|
||||
if (EnumerationUtil.isMaterialEditOnInteract(material)) {
|
||||
return MPerm.getPermBuild();
|
||||
}
|
||||
if (EnumerationUtil.isMaterialContainer(material)) {
|
||||
return MPerm.getPermContainer();
|
||||
}
|
||||
if (EnumerationUtil.isMaterialDoor(material)) {
|
||||
return MPerm.getPermDoor();
|
||||
}
|
||||
if (material == Material.STONE_BUTTON) {
|
||||
return MPerm.getPermButton();
|
||||
}
|
||||
if (material == Material.LEVER) {
|
||||
return MPerm.getPermLever();
|
||||
}
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user