f unstuck

This commit is contained in:
Olof Larsson 2015-08-28 10:42:40 +02:00
parent 8eaf1215d2
commit 3f3ee4df6d
5 changed files with 175 additions and 0 deletions

View File

@ -81,6 +81,7 @@ permissions:
factions.unclaim.circle: {description: unclaim by circle and radius, default: false} factions.unclaim.circle: {description: unclaim by circle and radius, default: false}
factions.unclaim.all: {description: unclaim all faction land, default: false} factions.unclaim.all: {description: unclaim all faction land, default: false}
factions.unsethome: {description: unset faction home, default: false} factions.unsethome: {description: unset faction home, default: false}
factions.unstuck: {description: teleport to nearest wilderness, default: false}
factions.version: {description: see plugin version, default: false} factions.version: {description: see plugin version, default: false}
# -------------------------------------------- # # -------------------------------------------- #
# STAR NOTATION # STAR NOTATION
@ -161,6 +162,7 @@ permissions:
factions.unclaim.circle: true factions.unclaim.circle: true
factions.unclaim.all: true factions.unclaim.all: true
factions.unsethome: true factions.unsethome: true
factions.unstuck: true
factions.version: true factions.version: true
# -------------------------------------------- # # -------------------------------------------- #
# KITS # KITS
@ -262,6 +264,7 @@ permissions:
factions.unclaim.circle: true factions.unclaim.circle: true
factions.unclaim.all: true factions.unclaim.all: true
factions.unsethome: true factions.unsethome: true
factions.unstuck: true
factions.version: true factions.version: true
factions.kit.default: factions.kit.default:
default: true default: true

View File

@ -81,6 +81,7 @@ public enum Perm
UNCLAIM_CIRCLE, UNCLAIM_CIRCLE,
UNCLAIM_ALL, UNCLAIM_ALL,
UNSETHOME, UNSETHOME,
UNSTUCK,
VERSION, VERSION,
// END OF LIST // END OF LIST

View File

@ -50,6 +50,7 @@ public class CmdFactions extends FactionsCommand
public CmdFactionsRelationEnemy cmdFactionsRelationEnemy = new CmdFactionsRelationEnemy(); public CmdFactionsRelationEnemy cmdFactionsRelationEnemy = new CmdFactionsRelationEnemy();
public CmdFactionsPerm cmdFactionsPerm = new CmdFactionsPerm(); public CmdFactionsPerm cmdFactionsPerm = new CmdFactionsPerm();
public CmdFactionsFlag cmdFactionsFlag = new CmdFactionsFlag(); public CmdFactionsFlag cmdFactionsFlag = new CmdFactionsFlag();
public CmdFactionsUnstuck cmdFactionsUnstuck = new CmdFactionsUnstuck();
public CmdFactionsExpansions cmdFactionsExpansions = new CmdFactionsExpansions(); public CmdFactionsExpansions cmdFactionsExpansions = new CmdFactionsExpansions();
public CmdFactionsXPlaceholder cmdFactionsTax = new CmdFactionsXPlaceholder("FactionsTax", "tax"); public CmdFactionsXPlaceholder cmdFactionsTax = new CmdFactionsXPlaceholder("FactionsTax", "tax");
public CmdFactionsXPlaceholder cmdFactionsDynmap = new CmdFactionsXPlaceholder("FactionsDynmap", "dynmap"); public CmdFactionsXPlaceholder cmdFactionsDynmap = new CmdFactionsXPlaceholder("FactionsDynmap", "dynmap");
@ -102,6 +103,7 @@ public class CmdFactions extends FactionsCommand
this.addSubCommand(this.cmdFactionsRelationEnemy); this.addSubCommand(this.cmdFactionsRelationEnemy);
this.addSubCommand(this.cmdFactionsPerm); this.addSubCommand(this.cmdFactionsPerm);
this.addSubCommand(this.cmdFactionsFlag); this.addSubCommand(this.cmdFactionsFlag);
this.addSubCommand(this.cmdFactionsUnstuck);
this.addSubCommand(this.cmdFactionsExpansions); this.addSubCommand(this.cmdFactionsExpansions);
this.addSubCommand(this.cmdFactionsTax); this.addSubCommand(this.cmdFactionsTax);
this.addSubCommand(this.cmdFactionsDynmap); this.addSubCommand(this.cmdFactionsDynmap);

View File

@ -0,0 +1,162 @@
package com.massivecraft.factions.cmd;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.World;
import com.massivecraft.factions.Perm;
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.massivecore.MassiveException;
import com.massivecraft.massivecore.cmd.req.ReqHasPerm;
import com.massivecraft.massivecore.cmd.req.ReqIsPlayer;
import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.mixin.TeleporterException;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.teleport.Destination;
import com.massivecraft.massivecore.teleport.DestinationSimple;
public class CmdFactionsUnstuck extends FactionsCommand
{
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public CmdFactionsUnstuck()
{
// Aliases
this.addAliases("unstuck");
// Requirements
this.addRequirements(ReqHasPerm.get(Perm.UNSTUCK.node));
this.addRequirements(ReqIsPlayer.get());
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public void perform() throws MassiveException
{
// If the player is in a chunk ...
final PS center = PS.valueOf(me.getLocation().getChunk());
// ... that isn't free ...
if (isFree(msender, center))
{
msg("<b>You don't seem to be stuck.");
}
// ... get the nearest free top location ...
Location location = getNearestFreeTopLocation(msender, center);
if (location == null)
{
msg("<b>No nearby chunk with %s<b> or build rights found.", FactionColl.get().getNone().describeTo(msender));
return;
}
// ... and schedule a teleport.
Destination destination = new DestinationSimple(PS.valueOf(location));
try
{
Mixin.teleport(me, destination, MConf.get().unstuckSeconds);
}
catch (TeleporterException e)
{
msg("<b>%s", e.getMessage());
}
}
// Get the first free top location in the spiral.
public static Location getNearestFreeTopLocation(MPlayer mplayer, PS ps)
{
List<PS> chunks = getChunkSpiral(ps);
for (PS chunk : chunks)
{
if (!isFree(mplayer, chunk)) continue;
Location ret = getTopLocation(chunk);
if (ret == null) continue;
return ret;
}
return null;
}
// Return the ground level top location for this ps.
public static Location getTopLocation(PS ps)
{
Location ret = null;
try
{
World world = ps.asBukkitWorld();
int blockX = ps.getBlockX(true);
int blockZ = ps.getBlockZ(true);
int blockY = world.getHighestBlockYAt(blockX, blockZ);
// We must have something to stand on.
if (blockY <= 1) return null;
double locationX = blockX + 0.5D;
double locationY = blockY + 0.5D;
double locationZ = blockZ + 0.5D;
ret = new Location(world, locationX, locationY, locationZ);
}
catch (Exception e)
{
e.printStackTrace();
}
return ret;
}
// With a "free" chunk we mean wilderness or that the player has build rights.
public static boolean isFree(MPlayer mplayer, PS ps)
{
Faction faction = BoardColl.get().getFactionAt(ps);
if (faction.isNone()) return true;
return MPerm.getPermBuild().has(mplayer, ps, false);
}
// Not exactly a spiral. But it will do.
public static List<PS> getChunkSpiral(PS center)
{
// Create Ret
List<PS> ret = new ArrayList<PS>();
// Fill Ret
center = center.getChunk(true);
final int centerX = center.getChunkX();
final int centerZ = center.getChunkZ();
for (int delta = 1; delta <= MConf.get().unstuckChunkRadius; delta++)
{
int minX = centerX - delta;
int maxX = centerX + delta;
int minZ = centerZ - delta;
int maxZ = centerZ + delta;
for (int x = minX; x <= maxX; x++)
{
ret.add(center.withChunkX(x).withChunkZ(minZ));
ret.add(center.withChunkX(x).withChunkZ(maxZ));
}
for (int z = minZ + 1; z <= maxZ - 1; z++)
{
ret.add(center.withChunkX(minX).withChunkZ(z));
ret.add(center.withChunkX(maxX).withChunkZ(z));
}
}
// Return Ret
return ret;
}
}

View File

@ -461,6 +461,13 @@ public class MConf extends Entity<MConf>
public float seeChunkParticleOffsetY = 2; public float seeChunkParticleOffsetY = 2;
public float seeChunkParticleDeltaY = 2; public float seeChunkParticleDeltaY = 2;
// -------------------------------------------- //
// UNSTUCK
// -------------------------------------------- //
public int unstuckSeconds = 30;
public int unstuckChunkRadius = 10;
// -------------------------------------------- // // -------------------------------------------- //
// LOGGING // LOGGING
// -------------------------------------------- // // -------------------------------------------- //