polygonal regions are now recognized by /region command, added extended AreaFlags data functions to ApplicableRegionSet, fixed isFlagAllowed in ApplicableRegionSet can only be executed once problem, updated region managers to not just forward all regions to ApplicableRegionSet

This commit is contained in:
Redecouverte 2011-02-24 14:24:23 +01:00
parent 17c8ed9ebc
commit b90fb6a2b0
6 changed files with 189 additions and 30 deletions

View File

@ -51,6 +51,7 @@
import com.sk89q.worldedit.blocks.ItemType;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.regions.Polygonal2DRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.TickSyncDelayLoggerFilter;
@ -61,6 +62,7 @@
import com.sk89q.worldguard.protection.regionmanager.GlobalRegionManager;
import com.sk89q.worldguard.protection.regions.AreaFlags;
import com.sk89q.worldguard.protection.regions.AreaFlags.State;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
import org.bukkit.World;
@ -808,11 +810,20 @@ private boolean handleRegionCommand(Player player, String action, String[] args)
LocalSession session = worldEdit.getSession(player);
Region weRegion = session.getSelection(new BukkitWorld(w));
BlockVector min = weRegion.getMinimumPoint().toBlockVector();
BlockVector max = weRegion.getMaximumPoint().toBlockVector();
ProtectedRegion region = new ProtectedCuboidRegion(id, min, max);
ProtectedRegion region;
if (weRegion instanceof Polygonal2DRegion) {
Polygonal2DRegion pweRegion = (Polygonal2DRegion) weRegion;
int minY = pweRegion.getMinimumPoint().getBlockY();
int maxY = pweRegion.getMaximumPoint().getBlockY();
region = new ProtectedPolygonalRegion(id, pweRegion.getPoints(), minY, maxY);
} else {
BlockVector min = weRegion.getMinimumPoint().toBlockVector();
BlockVector max = weRegion.getMaximumPoint().toBlockVector();
region = new ProtectedCuboidRegion(id, min, max);
}
if (args.length >= 2) {
region.setOwners(parseDomainString(args, 1));
}
@ -851,12 +862,20 @@ private boolean handleRegionCommand(Player player, String action, String[] args)
LocalSession session = worldEdit.getSession(player);
Region weRegion = session.getSelection(new BukkitWorld(player.getWorld()));
BlockVector min = weRegion.getMinimumPoint().toBlockVector();
BlockVector max = weRegion.getMaximumPoint().toBlockVector();
ProtectedRegion region = new ProtectedCuboidRegion(id, min, max);
ProtectedRegion region;
if (weRegion instanceof Polygonal2DRegion) {
Polygonal2DRegion pweRegion = (Polygonal2DRegion)weRegion;
int minY = pweRegion.getMinimumPoint().getBlockY();
int maxY = pweRegion.getMaximumPoint().getBlockY();
region = new ProtectedPolygonalRegion(id, pweRegion.getPoints(), minY, maxY);
} else {
BlockVector min = weRegion.getMinimumPoint().toBlockVector();
BlockVector max = weRegion.getMaximumPoint().toBlockVector();
region = new ProtectedCuboidRegion(id, min, max);
}
if (mgr.overlapsUnownedRegion(region, wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "This region overlaps with someone else's region.");
return true;

View File

@ -27,6 +27,8 @@
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.regions.AreaFlags;
import com.sk89q.worldguard.protection.regions.AreaFlags.State;
import java.util.ArrayList;
import java.util.List;
/**
* Represents a set of regions and their rules as applied to one point.
@ -36,7 +38,7 @@
public class ApplicableRegionSet {
private GlobalFlags global;
private Vector pt;
private Iterator<ProtectedRegion> applicable;
private List<ProtectedRegion> applicable;
/**
* Construct the object.
@ -45,7 +47,7 @@ public class ApplicableRegionSet {
* @param regions
* @param global
*/
public ApplicableRegionSet(Vector pt, Iterator<ProtectedRegion> applicable,
public ApplicableRegionSet(Vector pt, List<ProtectedRegion> applicable,
GlobalFlags global) {
this.pt = pt;
this.applicable = applicable;
@ -121,19 +123,26 @@ private boolean isFlagAllowed(String flag, boolean def, LocalPlayer player) {
Set<ProtectedRegion> needsClear = new HashSet<ProtectedRegion>();
Set<ProtectedRegion> hasCleared = new HashSet<ProtectedRegion>();
while (applicable.hasNext()) {
ProtectedRegion region = applicable.next();
Iterator<ProtectedRegion> iter = applicable.iterator();
while (iter.hasNext()) {
ProtectedRegion region = iter.next();
// Ignore non-build regions
if (player != null && region.getFlags().get(AreaFlags.FLAG_PASSTHROUGH) == State.ALLOW) {
continue;
}
/*
* No longer required.
* A RegionManager now only supplies regions containing pt.
*
// Forget about regions that are not covered
if (!region.contains(pt)) {
continue;
}
*/
// Allow DENY to override everything
if (region.getFlags().get(flag) == State.DENY) {
return false;
@ -172,7 +181,122 @@ private boolean isFlagAllowed(String flag, boolean def, LocalPlayer player) {
return (found == false ? def : allowed)
|| (player != null && needsClear.size() == 0);
}
/**
* Get an area flag
*
* @param name flag name
* @param subname flag subname
* @param inherit true to inherit flag values from parents
* @param player null to not check owners and members
* @return
*/
private String getAreaFlag(String name, String subname, Boolean inherit, LocalPlayer player) {
int appSize = applicable.size();
if(appSize < 1)
{
return null;
}
else if(appSize < 2)
{
return applicable.get(0).getFlags().getFlag(name, subname);
}
List<String> parents = new ArrayList<String>();
Iterator<ProtectedRegion> iter = applicable.iterator();
while (iter.hasNext()) {
ProtectedRegion region = iter.next();
ProtectedRegion parent = region.getParent();
if(parent == null)
{
parents.add(region.getId());
}
else
{
parents.add(parent.getId());
}
}
ProtectedRegion region = null;
iter = applicable.iterator();
while (iter.hasNext()) {
region = iter.next();
if(!parents.contains(region.getId()))
{
break;
}
}
if (player != null && !region.isMember(player)) {
return null;
}
if(!inherit)
{
return region.getFlags().getFlag(name, subname);
}
else
{
String value;
do
{
value = region.getFlags().getFlag(name, subname);
region = region.getParent();
} while(value == null && region != null);
return value;
}
}
public Boolean getBooleanAreaFlag(String name, String subname, Boolean inherit, LocalPlayer player)
{
String data = getAreaFlag(name, subname, inherit, player);
if(data == null)
{
return null;
}
return Boolean.valueOf(data);
}
public Integer getIntAreaFlag(String name, String subname, Boolean inherit, LocalPlayer player)
{
String data = getAreaFlag(name, subname, inherit, player);
if(data == null)
{
return null;
}
return Integer.valueOf(data);
}
public Float getFloatAreaFlag(String name, String subname, Boolean inherit, LocalPlayer player)
{
String data = getAreaFlag(name, subname, inherit, player);
if(data == null)
{
return null;
}
return Float.valueOf(data);
}
public Double getDoubleAreaFlag(String name, String subname, Boolean inherit, LocalPlayer player)
{
String data = getAreaFlag(name, subname, inherit, player);
if(data == null)
{
return null;
}
return Double.valueOf(data);
}
/**
* Clear a region's parents for isFlagAllowed().
*

View File

@ -76,10 +76,10 @@ public Map<String, ProtectedRegion> getRegions() {
String id = entry.getKey();
ProtectedRegion region = entry.getValue();
String parentId = region.getParentId();
if (parentId != null) {
ProtectedRegion parent = region.getParent();
if (parent != null) {
try {
region.setParent(ret.get(parentId));
region.setParent(ret.get(parent.getId()));
} catch (CircularInheritanceException ex) {
}
} else {

View File

@ -31,6 +31,7 @@
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
import com.sk89q.worldguard.protection.dbs.ProtectionDatabase;
import java.util.HashMap;
/**
@ -130,7 +131,16 @@ public ProtectedRegion getRegion(String id) {
* @return
*/
public ApplicableRegionSet getApplicableRegions(Vector pt) {
return new ApplicableRegionSet(pt, regions.values().iterator(), global);
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
for (Map.Entry<String,ProtectedRegion> entry : regions.entrySet()) {
if (entry.getValue().contains(pt)) {
appRegions.add(entry.getValue());
}
}
return new ApplicableRegionSet(pt, appRegions, global);
}
/**

View File

@ -34,6 +34,7 @@
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
import com.sk89q.worldguard.protection.dbs.ProtectionDatabase;
import java.io.IOException;
import java.util.HashMap;
public class PRTreeRegionManager extends RegionManager {
private static final int BRANCH_FACTOR = 30;
@ -144,7 +145,19 @@ public void removeRegion(String id) {
* @return
*/
public ApplicableRegionSet getApplicableRegions(Vector pt) {
return new ApplicableRegionSet(pt, regions.values().iterator(), global);
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
int x = pt.getBlockX();
int z = pt.getBlockZ();
for (ProtectedRegion region : tree.find(x, z, x, z)) {
if (region.contains(pt)) {
appRegions.add(region);
}
}
return new ApplicableRegionSet(pt, appRegions, global);
}
/**

View File

@ -84,13 +84,6 @@ public String getId() {
return id;
}
/**
* @return the parentId.
*/
public String getParentId() {
this.setParentId();
return parentId;
}
/**
* @set the parentId. Used for serialization, don't touch it.