Better claiming. Step 1.
This commit is contained in:
parent
b54293577d
commit
c690d33ad6
@ -1,5 +1,7 @@
|
|||||||
package com.massivecraft.factions.cmd;
|
package com.massivecraft.factions.cmd;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.massivecraft.factions.Perm;
|
import com.massivecraft.factions.Perm;
|
||||||
import com.massivecraft.factions.cmd.arg.ARFaction;
|
import com.massivecraft.factions.cmd.arg.ARFaction;
|
||||||
import com.massivecraft.factions.entity.Faction;
|
import com.massivecraft.factions.entity.Faction;
|
||||||
@ -50,7 +52,8 @@ public class CmdFactionsAutoClaim extends FactionsCommand
|
|||||||
msender.setAutoClaimFaction(forFaction);
|
msender.setAutoClaimFaction(forFaction);
|
||||||
|
|
||||||
msg("<i>Now auto-claiming land for <h>%s<i>.", forFaction.describeTo(msender));
|
msg("<i>Now auto-claiming land for <h>%s<i>.", forFaction.describeTo(msender));
|
||||||
msender.tryClaim(forFaction, PS.valueOf(me), true, true);
|
|
||||||
|
msender.tryClaim(forFaction, Collections.singletonList(PS.valueOf(me).getChunk(true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,11 +1,13 @@
|
|||||||
package com.massivecraft.factions.cmd;
|
package com.massivecraft.factions.cmd;
|
||||||
|
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.massivecraft.factions.Perm;
|
import com.massivecraft.factions.Perm;
|
||||||
import com.massivecraft.factions.cmd.arg.ARFaction;
|
import com.massivecraft.factions.cmd.arg.ARFaction;
|
||||||
import com.massivecraft.factions.entity.Faction;
|
import com.massivecraft.factions.entity.Faction;
|
||||||
import com.massivecraft.factions.entity.MConf;
|
import com.massivecraft.factions.entity.MConf;
|
||||||
import com.massivecraft.factions.entity.MPerm;
|
import com.massivecraft.factions.entity.MPerm;
|
||||||
import com.massivecraft.factions.task.SpiralTask;
|
|
||||||
import com.massivecraft.massivecore.cmd.arg.ARInteger;
|
import com.massivecraft.massivecore.cmd.arg.ARInteger;
|
||||||
import com.massivecraft.massivecore.cmd.req.ReqHasPerm;
|
import com.massivecraft.massivecore.cmd.req.ReqHasPerm;
|
||||||
import com.massivecraft.massivecore.cmd.req.ReqIsPlayer;
|
import com.massivecraft.massivecore.cmd.req.ReqIsPlayer;
|
||||||
@ -43,68 +45,52 @@ public class CmdFactionsClaim extends FactionsCommand
|
|||||||
Integer radius = this.arg(0, ARInteger.get(), 1);
|
Integer radius = this.arg(0, ARInteger.get(), 1);
|
||||||
if (radius == null) return;
|
if (radius == null) return;
|
||||||
|
|
||||||
final Faction forFaction = this.arg(1, ARFaction.get(), msenderFaction);
|
final Faction newFaction = this.arg(1, ARFaction.get(), msenderFaction);
|
||||||
if (forFaction == null) return;
|
if (newFaction == null) return;
|
||||||
|
|
||||||
// MPerm
|
// MPerm
|
||||||
if (forFaction.isNormal() && !MPerm.getPermTerritory().has(msender, forFaction, true)) return;
|
if (newFaction.isNormal() && ! MPerm.getPermTerritory().has(msender, newFaction, true)) return;
|
||||||
|
|
||||||
// Validate
|
// Radius Claim Min
|
||||||
if (radius < 1)
|
if (radius < 1)
|
||||||
{
|
{
|
||||||
msg("<b>If you specify a radius, it must be at least 1.");
|
msg("<b>If you specify a radius, it must be at least 1.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Radius Claim Perm
|
||||||
|
if (radius > 1 && ! Perm.CLAIM_RADIUS.has(sender, false))
|
||||||
|
{
|
||||||
|
msg("<b>You do not have permission to claim in a radius.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Radius Claim Max
|
||||||
if (radius > MConf.get().radiusClaimRadiusLimit && ! msender.isUsingAdminMode())
|
if (radius > MConf.get().radiusClaimRadiusLimit && ! msender.isUsingAdminMode())
|
||||||
{
|
{
|
||||||
msg("<b>The maximum radius allowed is <h>%s<b>.", MConf.get().radiusClaimRadiusLimit);
|
msg("<b>The maximum radius allowed is <h>%s<b>.", MConf.get().radiusClaimRadiusLimit);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply
|
// Get Chunks
|
||||||
|
final int radiusZero = radius -1;
|
||||||
// single chunk
|
final PS chunk = PS.valueOf(me).getChunk(true);
|
||||||
if (radius < 2)
|
final int xmin = chunk.getChunkX() - radiusZero;
|
||||||
|
final int xmax = chunk.getChunkX() + radiusZero;
|
||||||
|
final int zmin = chunk.getChunkZ() - radiusZero;
|
||||||
|
final int zmax = chunk.getChunkZ() + radiusZero;
|
||||||
|
Set<PS> chunks = new LinkedHashSet<PS>();
|
||||||
|
chunks.add(chunk); // The center should come first for pretty messages
|
||||||
|
for (int x = xmin; x <= xmax; x++)
|
||||||
{
|
{
|
||||||
msender.tryClaim(forFaction, PS.valueOf(me), true, true);
|
for (int z = zmin; z <= zmax; z++)
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// radius claim
|
|
||||||
if (!Perm.CLAIM_RADIUS.has(sender, false))
|
|
||||||
{
|
{
|
||||||
msg("<b>You do not have permission to claim in a radius.");
|
chunks.add(chunk.withChunkX(x).withChunkZ(z));
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: There must be a better way than using a spiral task.
|
// Apply / Inform
|
||||||
// TODO: Do some research to allow for claming sets of chunks in a batch with atomicity.
|
msender.tryClaim(newFaction, chunks);
|
||||||
// This will probably result in an alteration to the owner change event.
|
|
||||||
// It would possibly contain a set of chunks instead of a single chunk.
|
|
||||||
|
|
||||||
new SpiralTask(PS.valueOf(me), radius)
|
|
||||||
{
|
|
||||||
private int failCount = 0;
|
|
||||||
private final int limit = MConf.get().radiusClaimFailureLimit - 1;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean work()
|
|
||||||
{
|
|
||||||
boolean success = msender.tryClaim(forFaction, PS.valueOf(this.currentLocation()), true, true);
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
this.failCount = 0;
|
|
||||||
}
|
|
||||||
else if (this.failCount++ >= this.limit)
|
|
||||||
{
|
|
||||||
this.stop();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.massivecraft.factions.cmd;
|
package com.massivecraft.factions.cmd;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.massivecraft.factions.cmd.req.ReqHasFaction;
|
import com.massivecraft.factions.cmd.req.ReqHasFaction;
|
||||||
import com.massivecraft.factions.entity.Faction;
|
import com.massivecraft.factions.entity.Faction;
|
||||||
import com.massivecraft.factions.entity.FactionColl;
|
import com.massivecraft.factions.entity.FactionColl;
|
||||||
@ -37,7 +39,7 @@ public class CmdFactionsUnclaim extends FactionsCommand
|
|||||||
Faction newFaction = FactionColl.get().getNone();
|
Faction newFaction = FactionColl.get().getNone();
|
||||||
|
|
||||||
// Apply
|
// Apply
|
||||||
if (msender.tryClaim(newFaction, chunk, true, true)) return;
|
if (msender.tryClaim(newFaction, Collections.singletonList(chunk))) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package com.massivecraft.factions.cmd;
|
|||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.massivecraft.factions.Factions;
|
|
||||||
import com.massivecraft.factions.Perm;
|
import com.massivecraft.factions.Perm;
|
||||||
import com.massivecraft.factions.Rel;
|
import com.massivecraft.factions.Rel;
|
||||||
import com.massivecraft.factions.cmd.req.ReqHasFaction;
|
import com.massivecraft.factions.cmd.req.ReqHasFaction;
|
||||||
@ -10,9 +9,7 @@ import com.massivecraft.factions.cmd.req.ReqRoleIsAtLeast;
|
|||||||
import com.massivecraft.factions.entity.BoardColl;
|
import com.massivecraft.factions.entity.BoardColl;
|
||||||
import com.massivecraft.factions.entity.Faction;
|
import com.massivecraft.factions.entity.Faction;
|
||||||
import com.massivecraft.factions.entity.FactionColl;
|
import com.massivecraft.factions.entity.FactionColl;
|
||||||
import com.massivecraft.factions.entity.MConf;
|
|
||||||
import com.massivecraft.factions.entity.MPerm;
|
import com.massivecraft.factions.entity.MPerm;
|
||||||
import com.massivecraft.factions.event.EventFactionsChunkChange;
|
|
||||||
import com.massivecraft.massivecore.cmd.req.ReqHasPerm;
|
import com.massivecraft.massivecore.cmd.req.ReqHasPerm;
|
||||||
import com.massivecraft.massivecore.ps.PS;
|
import com.massivecraft.massivecore.ps.PS;
|
||||||
|
|
||||||
@ -49,12 +46,15 @@ public class CmdFactionsUnclaimall extends FactionsCommand
|
|||||||
|
|
||||||
// Apply
|
// Apply
|
||||||
Set<PS> chunks = BoardColl.get().getChunks(faction);
|
Set<PS> chunks = BoardColl.get().getChunks(faction);
|
||||||
|
msender.tryClaim(newFaction, chunks);
|
||||||
|
|
||||||
|
/*
|
||||||
int countTotal = chunks.size();
|
int countTotal = chunks.size();
|
||||||
int countSuccess = 0;
|
int countSuccess = 0;
|
||||||
int countFail = 0;
|
int countFail = 0;
|
||||||
for (PS chunk : chunks)
|
for (PS chunk : chunks)
|
||||||
{
|
{
|
||||||
EventFactionsChunkChange event = new EventFactionsChunkChange(sender, chunk, newFaction);
|
EventFactionsChunksChange event = new EventFactionsChunksChange(sender, chunk, newFaction);
|
||||||
event.run();
|
event.run();
|
||||||
if (event.isCancelled())
|
if (event.isCancelled())
|
||||||
{
|
{
|
||||||
@ -74,7 +74,8 @@ public class CmdFactionsUnclaimall extends FactionsCommand
|
|||||||
if (MConf.get().logLandUnclaims)
|
if (MConf.get().logLandUnclaims)
|
||||||
{
|
{
|
||||||
Factions.get().log(msender.getName()+" unclaimed everything for the faction: "+msenderFaction.getName());
|
Factions.get().log(msender.getName()+" unclaimed everything for the faction: "+msenderFaction.getName());
|
||||||
}
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
package com.massivecraft.factions.engine;
|
package com.massivecraft.factions.engine;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
@ -9,7 +14,7 @@ import com.massivecraft.factions.entity.Faction;
|
|||||||
import com.massivecraft.factions.entity.MConf;
|
import com.massivecraft.factions.entity.MConf;
|
||||||
import com.massivecraft.factions.entity.MPlayer;
|
import com.massivecraft.factions.entity.MPlayer;
|
||||||
import com.massivecraft.factions.event.EventFactionsAbstractSender;
|
import com.massivecraft.factions.event.EventFactionsAbstractSender;
|
||||||
import com.massivecraft.factions.event.EventFactionsChunkChange;
|
import com.massivecraft.factions.event.EventFactionsChunksChange;
|
||||||
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
|
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
|
||||||
import com.massivecraft.factions.event.EventFactionsCreate;
|
import com.massivecraft.factions.event.EventFactionsCreate;
|
||||||
import com.massivecraft.factions.event.EventFactionsDescriptionChange;
|
import com.massivecraft.factions.event.EventFactionsDescriptionChange;
|
||||||
@ -26,6 +31,8 @@ import com.massivecraft.factions.event.EventFactionsTitleChange;
|
|||||||
import com.massivecraft.factions.integration.Econ;
|
import com.massivecraft.factions.integration.Econ;
|
||||||
import com.massivecraft.massivecore.EngineAbstract;
|
import com.massivecraft.massivecore.EngineAbstract;
|
||||||
import com.massivecraft.massivecore.money.Money;
|
import com.massivecraft.massivecore.money.Money;
|
||||||
|
import com.massivecraft.massivecore.ps.PS;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
|
||||||
public class EngineEcon extends EngineAbstract
|
public class EngineEcon extends EngineAbstract
|
||||||
{
|
{
|
||||||
@ -116,13 +123,27 @@ public class EngineEcon extends EngineAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
public void payForAction(EventFactionsChunkChange event)
|
public void payForAction(EventFactionsChunksChange event)
|
||||||
{
|
{
|
||||||
EventFactionsChunkChangeType type = event.getType();
|
double cost = 0;
|
||||||
Double cost = MConf.get().econChunkCost.get(type);
|
List<String> typeNames = new ArrayList<String>();
|
||||||
|
|
||||||
String desc = type.toString().toLowerCase() + " this land";
|
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);
|
payForAction(event, cost, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,12 @@ package com.massivecraft.factions.engine;
|
|||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -62,12 +64,14 @@ import com.massivecraft.factions.Factions;
|
|||||||
import com.massivecraft.factions.Rel;
|
import com.massivecraft.factions.Rel;
|
||||||
import com.massivecraft.factions.TerritoryAccess;
|
import com.massivecraft.factions.TerritoryAccess;
|
||||||
import com.massivecraft.factions.entity.BoardColl;
|
import com.massivecraft.factions.entity.BoardColl;
|
||||||
|
import com.massivecraft.factions.entity.FactionColl;
|
||||||
import com.massivecraft.factions.entity.MFlag;
|
import com.massivecraft.factions.entity.MFlag;
|
||||||
import com.massivecraft.factions.entity.MPerm;
|
import com.massivecraft.factions.entity.MPerm;
|
||||||
import com.massivecraft.factions.entity.MPlayer;
|
import com.massivecraft.factions.entity.MPlayer;
|
||||||
import com.massivecraft.factions.entity.Faction;
|
import com.massivecraft.factions.entity.Faction;
|
||||||
import com.massivecraft.factions.entity.MConf;
|
import com.massivecraft.factions.entity.MConf;
|
||||||
import com.massivecraft.factions.entity.MPlayerColl;
|
import com.massivecraft.factions.entity.MPlayerColl;
|
||||||
|
import com.massivecraft.factions.event.EventFactionsChunksChange;
|
||||||
import com.massivecraft.factions.event.EventFactionsPvpDisallowed;
|
import com.massivecraft.factions.event.EventFactionsPvpDisallowed;
|
||||||
import com.massivecraft.factions.event.EventFactionsPowerChange;
|
import com.massivecraft.factions.event.EventFactionsPowerChange;
|
||||||
import com.massivecraft.factions.event.EventFactionsPowerChange.PowerChangeReason;
|
import com.massivecraft.factions.event.EventFactionsPowerChange.PowerChangeReason;
|
||||||
@ -230,6 +234,167 @@ public class EngineMain extends EngineAbstract
|
|||||||
// CHUNK CHANGE: DETECT
|
// CHUNK CHANGE: DETECT
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void onChunksChange(EventFactionsChunksChange event)
|
||||||
|
{
|
||||||
|
// Args
|
||||||
|
final MPlayer msender = event.getMSender();
|
||||||
|
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();
|
||||||
|
|
||||||
|
// Admin Mode? Sure!
|
||||||
|
if (msender.isUsingAdminMode()) 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 = Mixin.getWorldDisplayName(worldId);
|
||||||
|
msender.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(msender, 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)
|
||||||
|
{
|
||||||
|
msender.msg("<b>Factions must have at least <h>%s<b> members to claim land.", MConf.get().claimsRequireMinFactionMembers);
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... ensure the claim would not bypass the global max limit ...
|
||||||
|
int ownedLand = newFaction.getLandCount();
|
||||||
|
if (MConf.get().claimedLandsMax != 0 && ownedLand + chunks.size() > MConf.get().claimedLandsMax && ! newFaction.getFlag(MFlag.getFlagInfpower()))
|
||||||
|
{
|
||||||
|
msender.msg("<b>Limit reached. You can't claim more land.");
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... ensure the claim would not bypass the faction power ...
|
||||||
|
if (ownedLand + chunks.size() > newFaction.getPowerRounded())
|
||||||
|
{
|
||||||
|
msender.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(newFaction, nearbyFaction)) continue;
|
||||||
|
msender.sendMessage(claimnear.createDeniedMessage(msender, nearbyFaction));
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
msender.msg("<b>You can only claim additional land which is connected to your first claim or controlled by another faction!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msender.msg("<b>You can only claim additional land which is connected to your first claim!");
|
||||||
|
}
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each of the old factions ...
|
||||||
|
for (Faction oldFaction : currentFactions)
|
||||||
|
{
|
||||||
|
// ... that is an actual faction ...
|
||||||
|
if (oldFaction.isNone()) continue;
|
||||||
|
|
||||||
|
// ... for which the msender lacks permission ...
|
||||||
|
if (MPerm.getPermTerritory().has(msender, oldFaction, false)) continue;
|
||||||
|
|
||||||
|
// ... print the error message of choice ...
|
||||||
|
if (msender.hasFaction() && msender.getFaction() == oldFaction)
|
||||||
|
{
|
||||||
|
msender.sendMessage(MPerm.getPermTerritory().createDeniedMessage(msender, oldFaction));
|
||||||
|
}
|
||||||
|
else if ( ! MConf.get().claimingFromOthersAllowed)
|
||||||
|
{
|
||||||
|
msender.msg("<b>You may not claim land from others.");
|
||||||
|
}
|
||||||
|
else if (oldFaction.getRelationTo(newFaction).isAtLeast(Rel.TRUCE))
|
||||||
|
{
|
||||||
|
msender.msg("<b>You can't claim this land due to your relation with the current owner.");
|
||||||
|
}
|
||||||
|
else if ( ! oldFaction.hasLandInflation())
|
||||||
|
{
|
||||||
|
msender.msg("%s<i> owns this land and is strong enough to keep it.", oldFaction.getName(msender));
|
||||||
|
}
|
||||||
|
else if ( ! BoardColl.get().isAnyBorderPs(chunks))
|
||||||
|
{
|
||||||
|
msender.msg("<b>You must start claiming land at the border of the territory.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... and cancel.
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CHUNK CHANGE: DETECT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void chunkChangeDetect(PlayerMoveEvent event)
|
public void chunkChangeDetect(PlayerMoveEvent event)
|
||||||
{
|
{
|
||||||
@ -307,7 +472,7 @@ public class EngineMain extends EngineAbstract
|
|||||||
if (autoClaimFaction == null) return;
|
if (autoClaimFaction == null) return;
|
||||||
|
|
||||||
// ... try claim.
|
// ... try claim.
|
||||||
mplayer.tryClaim(autoClaimFaction, chunkTo, true, true);
|
mplayer.tryClaim(autoClaimFaction, Collections.singletonList(chunkTo));
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
@ -243,6 +243,16 @@ public class Board extends Entity<Board> implements BoardInterface
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnyBorderPs(Set<PS> pss)
|
||||||
|
{
|
||||||
|
for (PS ps : pss)
|
||||||
|
{
|
||||||
|
if (this.isBorderPs(ps)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Is this coord connected to any coord claimed by the specified faction?
|
// Is this coord connected to any coord claimed by the specified faction?
|
||||||
@Override
|
@Override
|
||||||
public boolean isConnectedPs(PS ps, Faction faction)
|
public boolean isConnectedPs(PS ps, Faction faction)
|
||||||
@ -266,6 +276,16 @@ public class Board extends Entity<Board> implements BoardInterface
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnyConnectedPs(Set<PS> pss, Faction faction)
|
||||||
|
{
|
||||||
|
for (PS ps : pss)
|
||||||
|
{
|
||||||
|
if (this.isConnectedPs(ps, faction)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// MAP GENERATION
|
// MAP GENERATION
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3,7 +3,9 @@ package com.massivecraft.factions.entity;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.massivecraft.factions.Const;
|
import com.massivecraft.factions.Const;
|
||||||
@ -150,6 +152,16 @@ public class BoardColl extends Coll<Board> implements BoardInterface
|
|||||||
return board.isBorderPs(ps);
|
return board.isBorderPs(ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnyBorderPs(Set<PS> pss)
|
||||||
|
{
|
||||||
|
for (PS ps : pss)
|
||||||
|
{
|
||||||
|
if (this.isBorderPs(ps)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isConnectedPs(PS ps, Faction faction)
|
public boolean isConnectedPs(PS ps, Faction faction)
|
||||||
{
|
{
|
||||||
@ -159,6 +171,16 @@ public class BoardColl extends Coll<Board> implements BoardInterface
|
|||||||
return board.isConnectedPs(ps, faction);
|
return board.isConnectedPs(ps, faction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnyConnectedPs(Set<PS> pss, Faction faction)
|
||||||
|
{
|
||||||
|
for (PS ps : pss)
|
||||||
|
{
|
||||||
|
if (this.isConnectedPs(ps, faction)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// MAP GENERATION
|
// MAP GENERATION
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -177,7 +199,7 @@ public class BoardColl extends Coll<Board> implements BoardInterface
|
|||||||
// Distance -1 returns 0 chunks always.
|
// Distance -1 returns 0 chunks always.
|
||||||
// Distance 0 returns 1 chunk only (the one supplied).
|
// Distance 0 returns 1 chunk only (the one supplied).
|
||||||
// Distance 1 returns 3x3 = 9 chunks.
|
// Distance 1 returns 3x3 = 9 chunks.
|
||||||
public static Set<PS> getNearbyChunks(PS chunk, int distance, boolean includeSelf)
|
public static Set<PS> getNearbyChunks(PS chunk, int distance)
|
||||||
{
|
{
|
||||||
// Fix Args
|
// Fix Args
|
||||||
if (chunk == null) throw new NullPointerException("chunk");
|
if (chunk == null) throw new NullPointerException("chunk");
|
||||||
@ -187,7 +209,6 @@ public class BoardColl extends Coll<Board> implements BoardInterface
|
|||||||
Set<PS> ret = new LinkedHashSet<PS>();
|
Set<PS> ret = new LinkedHashSet<PS>();
|
||||||
|
|
||||||
if (distance < 0) return ret;
|
if (distance < 0) return ret;
|
||||||
// if (distance == 0 && ! includeSelf) return ret; // This will be done by the code below.
|
|
||||||
|
|
||||||
// Main
|
// Main
|
||||||
int xmin = chunk.getChunkX() - distance;
|
int xmin = chunk.getChunkX() - distance;
|
||||||
@ -200,7 +221,6 @@ public class BoardColl extends Coll<Board> implements BoardInterface
|
|||||||
{
|
{
|
||||||
for (int z = zmin; z <= zmax; z++)
|
for (int z = zmin; z <= zmax; z++)
|
||||||
{
|
{
|
||||||
if ( ! includeSelf && x == chunk.getChunkX() && z == chunk.getChunkZ()) continue;
|
|
||||||
ret.add(chunk.withChunkX(x).withChunkZ(z));
|
ret.add(chunk.withChunkX(x).withChunkZ(z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,6 +229,26 @@ public class BoardColl extends Coll<Board> implements BoardInterface
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Set<PS> getNearbyChunks(Collection<PS> chunks, int distance)
|
||||||
|
{
|
||||||
|
// Fix Args
|
||||||
|
if (chunks == null) throw new NullPointerException("chunks");
|
||||||
|
|
||||||
|
// Create Ret
|
||||||
|
Set<PS> ret = new LinkedHashSet<PS>();
|
||||||
|
|
||||||
|
if (distance < 0) return ret;
|
||||||
|
|
||||||
|
// Main
|
||||||
|
for (PS chunk : chunks)
|
||||||
|
{
|
||||||
|
ret.addAll(getNearbyChunks(chunk, distance));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return Ret
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public static Set<Faction> getDistinctFactions(Collection<PS> chunks)
|
public static Set<Faction> getDistinctFactions(Collection<PS> chunks)
|
||||||
{
|
{
|
||||||
// Fix Args
|
// Fix Args
|
||||||
@ -229,4 +269,19 @@ public class BoardColl extends Coll<Board> implements BoardInterface
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Map<PS, Faction> getChunkFaction(Collection<PS> chunks)
|
||||||
|
{
|
||||||
|
Map<PS, Faction> ret = new LinkedHashMap<PS, Faction>();
|
||||||
|
|
||||||
|
for (PS chunk : chunks)
|
||||||
|
{
|
||||||
|
chunk = chunk.getChunk(true);
|
||||||
|
Faction faction = get().getFactionAt(chunk);
|
||||||
|
if (faction == null) faction = FactionColl.get().getNone();
|
||||||
|
ret.put(chunk, faction);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,9 @@ public interface BoardInterface
|
|||||||
|
|
||||||
// NEARBY DETECTION
|
// NEARBY DETECTION
|
||||||
public boolean isBorderPs(PS ps);
|
public boolean isBorderPs(PS ps);
|
||||||
|
public boolean isAnyBorderPs(Set<PS> pss);
|
||||||
public boolean isConnectedPs(PS ps, Faction faction);
|
public boolean isConnectedPs(PS ps, Faction faction);
|
||||||
|
public boolean isAnyConnectedPs(Set<PS> pss, Faction faction);
|
||||||
|
|
||||||
// MAP
|
// MAP
|
||||||
// TODO: Could the degrees be embedded in centerPs yaw instead?
|
// TODO: Could the degrees be embedded in centerPs yaw instead?
|
||||||
|
@ -151,9 +151,6 @@ public class MConf extends Entity<MConf>
|
|||||||
// CLAIM LIMITS
|
// CLAIM LIMITS
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
// if someone is doing a radius claim and the process fails to claim land this many times in a row, it will exit
|
|
||||||
public int radiusClaimFailureLimit = 9;
|
|
||||||
|
|
||||||
// the maximum radius allowed when using the claim command.
|
// the maximum radius allowed when using the claim command.
|
||||||
public int radiusClaimRadiusLimit = 5;
|
public int radiusClaimRadiusLimit = 5;
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.massivecraft.factions.entity;
|
package com.massivecraft.factions.entity;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -12,7 +15,8 @@ import com.massivecraft.factions.Lang;
|
|||||||
import com.massivecraft.factions.Perm;
|
import com.massivecraft.factions.Perm;
|
||||||
import com.massivecraft.factions.Rel;
|
import com.massivecraft.factions.Rel;
|
||||||
import com.massivecraft.factions.RelationParticipator;
|
import com.massivecraft.factions.RelationParticipator;
|
||||||
import com.massivecraft.factions.event.EventFactionsChunkChange;
|
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
|
||||||
|
import com.massivecraft.factions.event.EventFactionsChunksChange;
|
||||||
import com.massivecraft.factions.event.EventFactionsMembershipChange;
|
import com.massivecraft.factions.event.EventFactionsMembershipChange;
|
||||||
import com.massivecraft.factions.event.EventFactionsRemovePlayerMillis;
|
import com.massivecraft.factions.event.EventFactionsRemovePlayerMillis;
|
||||||
import com.massivecraft.factions.event.EventFactionsMembershipChange.MembershipChangeReason;
|
import com.massivecraft.factions.event.EventFactionsMembershipChange.MembershipChangeReason;
|
||||||
@ -793,163 +797,91 @@ public class MPlayer extends SenderEntity<MPlayer> implements EconomyParticipato
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean tryClaim(Faction newFaction, PS ps, boolean verbooseChange, boolean verbooseSame)
|
// NEW
|
||||||
|
public boolean tryClaim(Faction newFaction, Collection<PS> pss)
|
||||||
{
|
{
|
||||||
PS chunk = ps.getChunk(true);
|
// Args
|
||||||
Faction oldFaction = BoardColl.get().getFactionAt(chunk);
|
if (newFaction == null) throw new NullPointerException("newFaction");
|
||||||
|
|
||||||
MConf mconf = MConf.get();
|
if (pss == null) throw new NullPointerException("pss");
|
||||||
|
final Set<PS> chunks = PS.getDistinctChunks(pss);
|
||||||
|
|
||||||
// NoChange
|
// NoChange
|
||||||
if (newFaction == oldFaction)
|
// We clean the chunks further by removing what does not change.
|
||||||
|
// This is also very suggested cleaning of EventFactionsChunksChange input.
|
||||||
|
Iterator<PS> iter = chunks.iterator();
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
PS chunk = iter.next();
|
||||||
|
Faction oldFaction = BoardColl.get().getFactionAt(chunk);
|
||||||
|
if (newFaction == oldFaction) iter.remove();
|
||||||
|
}
|
||||||
|
if (chunks.isEmpty())
|
||||||
{
|
{
|
||||||
msg("%s<i> already owns this land.", newFaction.describeTo(this, true));
|
msg("%s<i> already owns this land.", newFaction.describeTo(this, true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! this.isUsingAdminMode())
|
|
||||||
{
|
|
||||||
if (newFaction.isNormal())
|
|
||||||
{
|
|
||||||
if ( ! mconf.worldsClaimingEnabled.contains(ps.getWorld()))
|
|
||||||
{
|
|
||||||
msg("<b>Sorry, this world has land claiming disabled.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! MPerm.getPermTerritory().has(this, newFaction, true))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newFaction.getMPlayers().size() < mconf.claimsRequireMinFactionMembers)
|
|
||||||
{
|
|
||||||
msg("Factions must have at least <h>%s<b> members to claim land.", mconf.claimsRequireMinFactionMembers);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ownedLand = newFaction.getLandCount();
|
|
||||||
|
|
||||||
if (mconf.claimedLandsMax != 0 && ownedLand >= mconf.claimedLandsMax && ! newFaction.getFlag(MFlag.getFlagInfpower()))
|
|
||||||
{
|
|
||||||
msg("<b>Limit reached. You can't claim more land.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ownedLand >= newFaction.getPowerRounded())
|
|
||||||
{
|
|
||||||
msg("<b>You can't claim more land. You need more power.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the factions nearby, excluding the chunk itself, the faction itself and the wilderness faction.
|
|
||||||
// The chunk itself is handled in the "if (oldFaction.isNormal())" section below.
|
|
||||||
Set<PS> nearbyChunks = BoardColl.getNearbyChunks(chunk, MConf.get().claimMinimumChunksDistanceToOthers, false);
|
|
||||||
Set<Faction> nearbyFactions = BoardColl.getDistinctFactions(nearbyChunks);
|
|
||||||
nearbyFactions.remove(FactionColl.get().getNone());
|
|
||||||
nearbyFactions.remove(newFaction);
|
|
||||||
// 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(newFaction, nearbyFaction)) continue;
|
|
||||||
sendMessage(claimnear.createDeniedMessage(this, nearbyFaction));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
mconf.claimsMustBeConnected
|
|
||||||
&&
|
|
||||||
newFaction.getLandCountInWorld(ps.getWorld()) > 0
|
|
||||||
&&
|
|
||||||
! BoardColl.get().isConnectedPs(chunk, newFaction)
|
|
||||||
&&
|
|
||||||
( ! mconf.claimsCanBeUnconnectedIfOwnedByOtherFaction || oldFaction.isNone())
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (mconf.claimsCanBeUnconnectedIfOwnedByOtherFaction)
|
|
||||||
{
|
|
||||||
msg("<b>You can only claim additional land which is connected to your first claim or controlled by another faction!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msg("<b>You can only claim additional land which is connected to your first claim!");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oldFaction.isNormal())
|
|
||||||
{
|
|
||||||
if ( ! MPerm.getPermTerritory().has(this, oldFaction, false))
|
|
||||||
{
|
|
||||||
if (this.hasFaction() && this.getFaction() == oldFaction)
|
|
||||||
{
|
|
||||||
sendMessage(MPerm.getPermTerritory().createDeniedMessage(this, oldFaction));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! mconf.claimingFromOthersAllowed)
|
|
||||||
{
|
|
||||||
msg("<b>You may not claim land from others.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oldFaction.getRelationTo(newFaction).isAtLeast(Rel.TRUCE))
|
|
||||||
{
|
|
||||||
msg("<b>You can't claim this land due to your relation with the current owner.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! oldFaction.hasLandInflation())
|
|
||||||
{
|
|
||||||
msg("%s<i> owns this land and is strong enough to keep it.", oldFaction.getName(this));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! BoardColl.get().isBorderPs(chunk))
|
|
||||||
{
|
|
||||||
msg("<b>You must start claiming land at the border of the territory.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Event
|
// Event
|
||||||
EventFactionsChunkChange event = new EventFactionsChunkChange(this.getSender(), chunk, newFaction);
|
// NOTE: We listen to this event ourselves at LOW.
|
||||||
|
// NOTE: That is where we apply the standard checks.
|
||||||
|
EventFactionsChunksChange event = new EventFactionsChunksChange(this.getSender(), chunks, newFaction);
|
||||||
event.run();
|
event.run();
|
||||||
if (event.isCancelled()) return false;
|
if (event.isCancelled()) return false;
|
||||||
|
|
||||||
// Apply
|
// Apply
|
||||||
|
for (PS chunk : chunks)
|
||||||
|
{
|
||||||
BoardColl.get().setFactionAt(chunk, newFaction);
|
BoardColl.get().setFactionAt(chunk, newFaction);
|
||||||
|
}
|
||||||
|
|
||||||
// Inform
|
// Inform
|
||||||
Set<MPlayer> informees = new HashSet<MPlayer>();
|
for (Entry<Faction, Set<PS>> entry : event.getOldFactionChunks().entrySet())
|
||||||
informees.add(this);
|
|
||||||
if (newFaction.isNormal())
|
|
||||||
{
|
{
|
||||||
informees.addAll(newFaction.getMPlayers());
|
final Faction oldFaction = entry.getKey();
|
||||||
}
|
final Set<PS> oldChunks = entry.getValue();
|
||||||
if (oldFaction.isNormal())
|
final PS oldChunk = oldChunks.iterator().next();
|
||||||
{
|
final Set<MPlayer> informees = getClaimInformees(this, oldFaction, newFaction);
|
||||||
informees.addAll(oldFaction.getMPlayers());
|
final EventFactionsChunkChangeType type = EventFactionsChunkChangeType.get(oldFaction, newFaction, this.getFaction());
|
||||||
}
|
|
||||||
if (MConf.get().logLandClaims)
|
String chunkString = oldChunk.toString(PSFormatHumanSpace.get());
|
||||||
{
|
String typeString = type.past;
|
||||||
informees.add(MPlayer.get(IdUtil.getConsole()));
|
|
||||||
}
|
|
||||||
|
|
||||||
String chunkString = chunk.toString(PSFormatHumanSpace.get());
|
|
||||||
String typeString = event.getType().past;
|
|
||||||
for (MPlayer informee : informees)
|
for (MPlayer informee : informees)
|
||||||
{
|
{
|
||||||
informee.msg("<h>%s<i> %s %s <i>| <h>%s<i> --> <h>%s", this.describeTo(informee, true), typeString, chunkString, oldFaction.describeTo(informee, true), newFaction.describeTo(informee, true));
|
informee.msg("<h>%s<i> %s <h>%d <i>" + (oldChunks.size() == 1 ? "chunk" : "chunks") + " near %s", this.describeTo(informee, true), typeString, oldChunks.size(), chunkString);
|
||||||
|
informee.msg(" <h>%s<i> --> <h>%s", oldFaction.describeTo(informee, true), newFaction.describeTo(informee, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Success
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// UTIL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static Set<MPlayer> getClaimInformees(MPlayer msender, Faction... factions)
|
||||||
|
{
|
||||||
|
Set<MPlayer> ret = new HashSet<MPlayer>();
|
||||||
|
|
||||||
|
ret.add(msender);
|
||||||
|
|
||||||
|
for (Faction faction : factions)
|
||||||
|
{
|
||||||
|
if (faction.isNormal())
|
||||||
|
{
|
||||||
|
ret.addAll(faction.getMPlayers());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MConf.get().logLandClaims)
|
||||||
|
{
|
||||||
|
ret.add(MPlayer.get(IdUtil.getConsole()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
package com.massivecraft.factions.event;
|
|
||||||
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.entity.BoardColl;
|
|
||||||
import com.massivecraft.factions.entity.Faction;
|
|
||||||
import com.massivecraft.factions.entity.MPlayer;
|
|
||||||
import com.massivecraft.massivecore.ps.PS;
|
|
||||||
|
|
||||||
public class EventFactionsChunkChange extends EventFactionsAbstractSender
|
|
||||||
{
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// REQUIRED EVENT CODE
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
private static final HandlerList handlers = new HandlerList();
|
|
||||||
@Override public HandlerList getHandlers() { return handlers; }
|
|
||||||
public static HandlerList getHandlerList() { return handlers; }
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// FIELDS
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
private final PS chunk;
|
|
||||||
public PS getChunk() { return this.chunk; }
|
|
||||||
|
|
||||||
private final Faction currentFaction;
|
|
||||||
private final Faction newFaction;
|
|
||||||
public Faction getNewFaction() { return this.newFaction; }
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// CONSTRUCT
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
public EventFactionsChunkChange(CommandSender sender, PS chunk, Faction newFaction)
|
|
||||||
{
|
|
||||||
super(sender);
|
|
||||||
this.chunk = chunk.getChunk(true);
|
|
||||||
this.currentFaction = BoardColl.get().getFactionAt(chunk);
|
|
||||||
this.newFaction = newFaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// UTIL
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
public EventFactionsChunkChangeType getType()
|
|
||||||
{
|
|
||||||
if (currentFaction.isNone()) return EventFactionsChunkChangeType.BUY;
|
|
||||||
if (newFaction.isNormal()) return EventFactionsChunkChangeType.CONQUER;
|
|
||||||
|
|
||||||
MPlayer usender = this.getMSender();
|
|
||||||
if (usender != null && usender.getFaction() == currentFaction) return EventFactionsChunkChangeType.SELL;
|
|
||||||
|
|
||||||
return EventFactionsChunkChangeType.PILLAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,11 +1,14 @@
|
|||||||
package com.massivecraft.factions.event;
|
package com.massivecraft.factions.event;
|
||||||
|
|
||||||
|
import com.massivecraft.factions.entity.Faction;
|
||||||
|
|
||||||
public enum EventFactionsChunkChangeType
|
public enum EventFactionsChunkChangeType
|
||||||
{
|
{
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// ENUM
|
// ENUM
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
NONE("none", "none"),
|
||||||
BUY("buy", "bought"),
|
BUY("buy", "bought"),
|
||||||
SELL("sell", "sold"),
|
SELL("sell", "sold"),
|
||||||
CONQUER("conquer", "conquered"),
|
CONQUER("conquer", "conquered"),
|
||||||
@ -31,4 +34,17 @@ public enum EventFactionsChunkChangeType
|
|||||||
this.past = past;
|
this.past = past;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// UTIL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static EventFactionsChunkChangeType get(Faction oldFaction, Faction newFaction, Faction self)
|
||||||
|
{
|
||||||
|
if (newFaction == oldFaction) return NONE;
|
||||||
|
if (oldFaction.isNone()) return BUY;
|
||||||
|
if (newFaction.isNormal()) return CONQUER;
|
||||||
|
if (oldFaction == self) return SELL;
|
||||||
|
return PILLAGE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
package com.massivecraft.factions.event;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
|
import com.massivecraft.factions.entity.BoardColl;
|
||||||
|
import com.massivecraft.factions.entity.Faction;
|
||||||
|
import com.massivecraft.factions.entity.MPlayer;
|
||||||
|
import com.massivecraft.massivecore.ps.PS;
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
|
||||||
|
public class EventFactionsChunksChange extends EventFactionsAbstractSender
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// REQUIRED EVENT CODE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
@Override public HandlerList getHandlers() { return handlers; }
|
||||||
|
public static HandlerList getHandlerList() { return handlers; }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private final Set<PS> chunks;
|
||||||
|
public Set<PS> getChunks() { return this.chunks; }
|
||||||
|
|
||||||
|
private final Faction newFaction;
|
||||||
|
public Faction getNewFaction() { return this.newFaction; }
|
||||||
|
|
||||||
|
private final Map<PS, Faction> oldChunkFaction;
|
||||||
|
public Map<PS, Faction> getOldChunkFaction() { return this.oldChunkFaction; }
|
||||||
|
|
||||||
|
private final Map<Faction, Set<PS>> oldFactionChunks;
|
||||||
|
public Map<Faction, Set<PS>> getOldFactionChunks() { return this.oldFactionChunks; }
|
||||||
|
|
||||||
|
private final Map<PS, EventFactionsChunkChangeType> chunkType;
|
||||||
|
public Map<PS, EventFactionsChunkChangeType> getChunkType() { return this.chunkType; }
|
||||||
|
|
||||||
|
private final Map<EventFactionsChunkChangeType, Set<PS>> typeChunks;
|
||||||
|
public Map<EventFactionsChunkChangeType, Set<PS>> getTypeChunks() { return this.typeChunks; }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public EventFactionsChunksChange(CommandSender sender, Set<PS> chunks, Faction newFaction)
|
||||||
|
{
|
||||||
|
super(sender);
|
||||||
|
chunks = PS.getDistinctChunks(chunks);
|
||||||
|
this.chunks = Collections.unmodifiableSet(chunks);
|
||||||
|
this.newFaction = newFaction;
|
||||||
|
this.oldChunkFaction = Collections.unmodifiableMap(BoardColl.getChunkFaction(chunks));
|
||||||
|
this.oldFactionChunks = Collections.unmodifiableMap(MUtil.reverseIndex(this.oldChunkFaction));
|
||||||
|
|
||||||
|
MPlayer msender = this.getMSender();
|
||||||
|
Faction self = null;
|
||||||
|
if (msender != null) self = msender.getFaction();
|
||||||
|
Map<PS, EventFactionsChunkChangeType> currentChunkType = new LinkedHashMap<PS, EventFactionsChunkChangeType>();
|
||||||
|
for (Entry<PS, Faction> entry : this.oldChunkFaction.entrySet())
|
||||||
|
{
|
||||||
|
PS chunk = entry.getKey();
|
||||||
|
Faction from = entry.getValue();
|
||||||
|
currentChunkType.put(chunk, EventFactionsChunkChangeType.get(from, newFaction, self));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.chunkType = Collections.unmodifiableMap(currentChunkType);
|
||||||
|
this.typeChunks = Collections.unmodifiableMap(MUtil.reverseIndex(this.chunkType));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,9 @@
|
|||||||
package com.massivecraft.factions.integration.lwc;
|
package com.massivecraft.factions.integration.lwc;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@ -14,7 +17,7 @@ import com.massivecraft.factions.Factions;
|
|||||||
import com.massivecraft.factions.entity.Faction;
|
import com.massivecraft.factions.entity.Faction;
|
||||||
import com.massivecraft.factions.entity.MConf;
|
import com.massivecraft.factions.entity.MConf;
|
||||||
import com.massivecraft.factions.entity.MPlayer;
|
import com.massivecraft.factions.entity.MPlayer;
|
||||||
import com.massivecraft.factions.event.EventFactionsChunkChange;
|
import com.massivecraft.factions.event.EventFactionsChunksChange;
|
||||||
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
|
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
|
||||||
import com.massivecraft.massivecore.EngineAbstract;
|
import com.massivecraft.massivecore.EngineAbstract;
|
||||||
import com.massivecraft.massivecore.ps.PS;
|
import com.massivecraft.massivecore.ps.PS;
|
||||||
@ -59,12 +62,9 @@ public class EngineLwc extends EngineAbstract
|
|||||||
// LISTENER
|
// LISTENER
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
public void removeProtectionsOnChunkChange(Faction newFaction, EventFactionsChunkChangeType type, Set<PS> chunks)
|
||||||
public void removeProtectionsOnChunkChange(EventFactionsChunkChange event)
|
|
||||||
{
|
{
|
||||||
// If we are supposed to clear at this chunk change type ...
|
// If we are supposed to clear at this chunk change type ...
|
||||||
Faction newFaction = event.getNewFaction();
|
|
||||||
EventFactionsChunkChangeType type = event.getType();
|
|
||||||
Boolean remove = MConf.get().lwcRemoveOnChange.get(type);
|
Boolean remove = MConf.get().lwcRemoveOnChange.get(type);
|
||||||
if (remove == null) return;
|
if (remove == null) return;
|
||||||
if (remove == false) return;
|
if (remove == false) return;
|
||||||
@ -72,7 +72,26 @@ public class EngineLwc extends EngineAbstract
|
|||||||
// ... then remove for all other factions than the new one.
|
// ... then remove for all other factions than the new one.
|
||||||
// First we wait one tick to make sure the chunk ownership changes have been applied.
|
// First we wait one tick to make sure the chunk ownership changes have been applied.
|
||||||
// Then we remove the protections but we do it asynchronously to not lock the main thread.
|
// Then we remove the protections but we do it asynchronously to not lock the main thread.
|
||||||
removeAlienProtectionsAsyncNextTick(event.getChunk(), newFaction);
|
for (PS chunk : chunks)
|
||||||
|
{
|
||||||
|
removeAlienProtectionsAsyncNextTick(chunk, newFaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeProtectionsOnChunkChange(Faction newFaction, Map<EventFactionsChunkChangeType, Set<PS>> typeChunks)
|
||||||
|
{
|
||||||
|
for (Entry<EventFactionsChunkChangeType, Set<PS>> typeChunk : typeChunks.entrySet())
|
||||||
|
{
|
||||||
|
final EventFactionsChunkChangeType type = typeChunk.getKey();
|
||||||
|
final Set<PS> chunks = typeChunk.getValue();
|
||||||
|
removeProtectionsOnChunkChange(newFaction, type, chunks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void removeProtectionsOnChunkChange(EventFactionsChunksChange event)
|
||||||
|
{
|
||||||
|
removeProtectionsOnChunkChange(event.getNewFaction(), event.getTypeChunks());
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
@ -1,216 +0,0 @@
|
|||||||
package com.massivecraft.factions.task;
|
|
||||||
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.Factions;
|
|
||||||
import com.massivecraft.massivecore.ps.PS;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* reference diagram, task should move in this pattern out from chunk 0 in the center.
|
|
||||||
* 8 [>][>][>][>][>] etc.
|
|
||||||
* [^][6][>][>][>][>][>][6]
|
|
||||||
* [^][^][4][>][>][>][4][v]
|
|
||||||
* [^][^][^][2][>][2][v][v]
|
|
||||||
* [^][^][^][^][0][v][v][v]
|
|
||||||
* [^][^][^][1][1][v][v][v]
|
|
||||||
* [^][^][3][<][<][3][v][v]
|
|
||||||
* [^][5][<][<][<][<][5][v]
|
|
||||||
* [7][<][<][<][<][<][<][7]
|
|
||||||
*/
|
|
||||||
|
|
||||||
public abstract class SpiralTask implements Runnable
|
|
||||||
{
|
|
||||||
// general task-related reference data
|
|
||||||
private transient World world = null;
|
|
||||||
private transient boolean readyToGo = false;
|
|
||||||
private transient int taskID = -1;
|
|
||||||
private transient int limit = 0;
|
|
||||||
|
|
||||||
// values for the spiral pattern routine
|
|
||||||
private transient int x = 0;
|
|
||||||
private transient int z = 0;
|
|
||||||
private transient boolean isZLeg = false;
|
|
||||||
private transient boolean isNeg = false;
|
|
||||||
private transient int length = -1;
|
|
||||||
private transient int current = 0;
|
|
||||||
|
|
||||||
// @SuppressWarnings("LeakingThisInConstructor") This actually triggers a warning in Eclipse xD Could we find another way to suppress the error please? :)
|
|
||||||
public SpiralTask(PS chunk, int radius)
|
|
||||||
{
|
|
||||||
chunk = chunk.getChunk(true);
|
|
||||||
|
|
||||||
// limit is determined based on spiral leg length for given radius; see insideRadius()
|
|
||||||
this.limit = (radius - 1) * 2;
|
|
||||||
|
|
||||||
this.world = Bukkit.getWorld(chunk.getWorld());
|
|
||||||
if (this.world == null)
|
|
||||||
{
|
|
||||||
Factions.get().log(Level.WARNING, "[SpiralTask] A valid world must be specified!");
|
|
||||||
this.stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.x = (int)chunk.getChunkX();
|
|
||||||
this.z = (int)chunk.getChunkZ();
|
|
||||||
|
|
||||||
this.readyToGo = true;
|
|
||||||
|
|
||||||
// get this party started
|
|
||||||
this.setTaskID(Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(Factions.get(), this, 2, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is where the necessary work is done; you'll need to override this method with whatever you want
|
|
||||||
* done at each chunk in the spiral pattern.
|
|
||||||
* Return false if the entire task needs to be aborted, otherwise return true to continue.
|
|
||||||
*/
|
|
||||||
public abstract boolean work();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a PS pointing at the current chunk X and Z values.
|
|
||||||
*/
|
|
||||||
public final PS currentChunk()
|
|
||||||
{
|
|
||||||
return PS.valueOf(this.world.getName(), null, null, null, null, null, null, this.x, this.z, null, null, null, null, null);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Returns a Location pointing at the current chunk X and Z values.
|
|
||||||
* note that the Location is at the corner of the chunk, not the center.
|
|
||||||
*/
|
|
||||||
public final Location currentLocation()
|
|
||||||
{
|
|
||||||
|
|
||||||
return new Location(world, this.x * 16, 65.0, this.z * 16);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Returns current chunk X and Z values.
|
|
||||||
*/
|
|
||||||
public final int getX()
|
|
||||||
{
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
public final int getZ()
|
|
||||||
{
|
|
||||||
return z;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Below are the guts of the class, which you normally wouldn't need to mess with.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public final void setTaskID(int ID)
|
|
||||||
{
|
|
||||||
if (ID == -1)
|
|
||||||
this.stop();
|
|
||||||
taskID = ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void run()
|
|
||||||
{
|
|
||||||
if (!this.valid() || !readyToGo) return;
|
|
||||||
|
|
||||||
// this is set so it only does one iteration at a time, no matter how frequently the timer fires
|
|
||||||
readyToGo = false;
|
|
||||||
|
|
||||||
// make sure we're still inside the specified radius
|
|
||||||
if ( ! this.insideRadius()) return;
|
|
||||||
|
|
||||||
// track this to keep one iteration from dragging on too long and possibly choking the system
|
|
||||||
long loopStartTime = now();
|
|
||||||
|
|
||||||
// keep going until the task has been running for 20ms or more, then stop to take a breather
|
|
||||||
while (now() < loopStartTime + 20)
|
|
||||||
{
|
|
||||||
// run the primary task on the current X/Z coordinates
|
|
||||||
if ( ! this.work())
|
|
||||||
{
|
|
||||||
this.finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// move on to next chunk in spiral
|
|
||||||
if ( ! this.moveToNext())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ready for the next iteration to run
|
|
||||||
readyToGo = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// step through chunks in spiral pattern from center; returns false if we're done, otherwise returns true
|
|
||||||
public final boolean moveToNext()
|
|
||||||
{
|
|
||||||
if ( ! this.valid()) return false;
|
|
||||||
|
|
||||||
// make sure we don't need to turn down the next leg of the spiral
|
|
||||||
if (current < length)
|
|
||||||
{
|
|
||||||
current++;
|
|
||||||
|
|
||||||
// if we're outside the radius, we're done
|
|
||||||
if ( ! this.insideRadius()) return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // one leg/side of the spiral down...
|
|
||||||
current = 0;
|
|
||||||
isZLeg ^= true;
|
|
||||||
// every second leg (between X and Z legs, negative or positive), length increases
|
|
||||||
if (isZLeg)
|
|
||||||
{
|
|
||||||
isNeg ^= true;
|
|
||||||
length++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// move one chunk further in the appropriate direction
|
|
||||||
if (isZLeg)
|
|
||||||
z += (isNeg) ? -1 : 1;
|
|
||||||
else
|
|
||||||
x += (isNeg) ? -1 : 1;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean insideRadius()
|
|
||||||
{
|
|
||||||
boolean inside = current < limit;
|
|
||||||
if (!inside)
|
|
||||||
this.finish();
|
|
||||||
return inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
// for successful completion
|
|
||||||
public void finish()
|
|
||||||
{
|
|
||||||
// P.p.log("SpiralTask successfully completed!");
|
|
||||||
this.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// we're done, whether finished or cancelled
|
|
||||||
public final void stop()
|
|
||||||
{
|
|
||||||
if (!this.valid()) return;
|
|
||||||
|
|
||||||
readyToGo = false;
|
|
||||||
Bukkit.getServer().getScheduler().cancelTask(taskID);
|
|
||||||
taskID = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// is this task still valid/workable?
|
|
||||||
public final boolean valid()
|
|
||||||
{
|
|
||||||
return taskID != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long now()
|
|
||||||
{
|
|
||||||
return System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user