Added support for "low" walls/attachments.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3697 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -35,11 +35,7 @@ import com.threerings.media.image.Colorization;
|
|||||||
*/
|
*/
|
||||||
public class ObjectTileSet extends SwissArmyTileSet
|
public class ObjectTileSet extends SwissArmyTileSet
|
||||||
implements RecolorableTileSet
|
implements RecolorableTileSet
|
||||||
{
|
{
|
||||||
/** A constraint prefix indicating that the object must be attached to a
|
|
||||||
* wall facing the suffixed direction (N, E, S, or W). */
|
|
||||||
public static final String ATTACH = "ATTACH_";
|
|
||||||
|
|
||||||
/** A constraint prefix indicating that the object must have empty space in
|
/** A constraint prefix indicating that the object must have empty space in
|
||||||
* the suffixed direction (N, E, S, or W). */
|
* the suffixed direction (N, E, S, or W). */
|
||||||
public static final String SPACE = "SPACE_";
|
public static final String SPACE = "SPACE_";
|
||||||
@@ -50,14 +46,23 @@ public class ObjectTileSet extends SwissArmyTileSet
|
|||||||
/** A constraint indicating that the object must be placed on a surface. */
|
/** A constraint indicating that the object must be placed on a surface. */
|
||||||
public static final String ON_SURFACE = "ON_SURFACE";
|
public static final String ON_SURFACE = "ON_SURFACE";
|
||||||
|
|
||||||
/** A constraint prefix indicating that the object is a wall facing the
|
/** A constraint prefix indicating that the object is a normal-height wall
|
||||||
* suffixed direction (N, E, S, or W). */
|
* facing the suffixed direction (N, E, S, or W). */
|
||||||
public static final String WALL = "WALL_";
|
public static final String WALL = "WALL_";
|
||||||
|
|
||||||
/** A constraint prefix indicating that the object must be placed on a wall
|
/** A constraint prefix indicating that the object must be placed on a
|
||||||
* facing the suffixed direction (N, E, S, or W). */
|
* normal-height wall facing the suffixed direction (N, E, S, or W). */
|
||||||
public static final String ON_WALL = "ON_WALL_";
|
public static final String ON_WALL = "ON_WALL_";
|
||||||
|
|
||||||
|
/** A constraint prefix indicating that the object must be attached to a
|
||||||
|
* wall facing the suffixed direction (N, E, S, or W). */
|
||||||
|
public static final String ATTACH = "ATTACH_";
|
||||||
|
|
||||||
|
/** The low suffix for walls and attachments. Low attachments can be placed
|
||||||
|
* on low or normal walls; normal attachments can only be placed on normal
|
||||||
|
* walls. */
|
||||||
|
public static final String LOW = "_LOW";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the widths (in unit tile count) of the objects in this
|
* Sets the widths (in unit tile count) of the objects in this
|
||||||
* tileset. This must be accompanied by a call to {@link
|
* tileset. This must be accompanied by a call to {@link
|
||||||
|
|||||||
@@ -155,6 +155,8 @@ public class PlacementConstraints
|
|||||||
protected String allowModifyObjects (ObjectData[] added,
|
protected String allowModifyObjects (ObjectData[] added,
|
||||||
ObjectData[] removed)
|
ObjectData[] removed)
|
||||||
{
|
{
|
||||||
|
DirectionHeight dirheight = new DirectionHeight();
|
||||||
|
|
||||||
for (int i = 0; i < added.length; i++) {
|
for (int i = 0; i < added.length; i++) {
|
||||||
if (added[i].tile.hasConstraint(ObjectTileSet.ON_SURFACE) &&
|
if (added[i].tile.hasConstraint(ObjectTileSet.ON_SURFACE) &&
|
||||||
!isOnSurface(added[i], added, removed)) {
|
!isOnSurface(added[i], added, removed)) {
|
||||||
@@ -168,8 +170,9 @@ public class PlacementConstraints
|
|||||||
"m.not_on_wall");
|
"m.not_on_wall");
|
||||||
}
|
}
|
||||||
|
|
||||||
dir = getConstraintDirection(added[i], ObjectTileSet.ATTACH);
|
if (getConstraintDirectionHeight(added[i], ObjectTileSet.ATTACH,
|
||||||
if (dir != NONE && !isAttached(added[i], added, removed, dir)) {
|
dirheight) && !isAttached(added[i], added, removed,
|
||||||
|
dirheight.dir, dirheight.low)) {
|
||||||
return MessageBundle.qualify(STAGE_MESSAGE_BUNDLE,
|
return MessageBundle.qualify(STAGE_MESSAGE_BUNDLE,
|
||||||
"m.not_attached");
|
"m.not_attached");
|
||||||
}
|
}
|
||||||
@@ -252,12 +255,15 @@ public class PlacementConstraints
|
|||||||
protected boolean hasAttached (ObjectData data, ObjectData[] added,
|
protected boolean hasAttached (ObjectData data, ObjectData[] added,
|
||||||
ObjectData[] removed, int dir)
|
ObjectData[] removed, int dir)
|
||||||
{
|
{
|
||||||
|
DirectionHeight dirheight = new DirectionHeight();
|
||||||
|
|
||||||
ArrayList objects = getObjectData(getAdjacentEdge(data.bounds,
|
ArrayList objects = getObjectData(getAdjacentEdge(data.bounds,
|
||||||
DirectionUtil.getOpposite(dir)), added, removed);
|
DirectionUtil.getOpposite(dir)), added, removed);
|
||||||
for (int i = 0, size = objects.size(); i < size; i++) {
|
for (int i = 0, size = objects.size(); i < size; i++) {
|
||||||
ObjectData odata = (ObjectData)objects.get(i);
|
ObjectData odata = (ObjectData)objects.get(i);
|
||||||
if (getConstraintDirection(odata, ObjectTileSet.ATTACH) == dir &&
|
if (getConstraintDirectionHeight(odata, ObjectTileSet.ATTACH,
|
||||||
!isAttached(odata, added, removed, dir)) {
|
dirheight) && !isAttached(odata, added, removed,
|
||||||
|
dirheight.dir, dirheight.low)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -303,7 +309,8 @@ public class PlacementConstraints
|
|||||||
protected boolean isOnSurface (ObjectData data, ObjectData[] added,
|
protected boolean isOnSurface (ObjectData data, ObjectData[] added,
|
||||||
ObjectData[] removed)
|
ObjectData[] removed)
|
||||||
{
|
{
|
||||||
return isCovered(data.bounds, added, removed, ObjectTileSet.SURFACE);
|
return isCovered(data.bounds, added, removed, ObjectTileSet.SURFACE,
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -314,27 +321,29 @@ public class PlacementConstraints
|
|||||||
ObjectData[] removed, int dir)
|
ObjectData[] removed, int dir)
|
||||||
{
|
{
|
||||||
return isCovered(data.bounds, added, removed,
|
return isCovered(data.bounds, added, removed,
|
||||||
getDirectionalConstraint(ObjectTileSet.WALL, dir));
|
getDirectionalConstraint(ObjectTileSet.WALL, dir), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the specified object is attached to another object in
|
* Determines whether the specified object is attached to another object in
|
||||||
* the specified direction.
|
* the specified direction and at the specified height.
|
||||||
*/
|
*/
|
||||||
protected boolean isAttached (ObjectData data, ObjectData[] added,
|
protected boolean isAttached (ObjectData data, ObjectData[] added,
|
||||||
ObjectData[] removed, int dir)
|
ObjectData[] removed, int dir, boolean low)
|
||||||
{
|
{
|
||||||
return isCovered(getAdjacentEdge(data.bounds, dir), added, removed,
|
return isCovered(getAdjacentEdge(data.bounds, dir), added, removed,
|
||||||
getDirectionalConstraint(ObjectTileSet.WALL, dir));
|
getDirectionalConstraint(ObjectTileSet.WALL, dir), low ?
|
||||||
|
getDirectionalConstraint(ObjectTileSet.WALL, dir, true) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a rectangle, determines whether all of the tiles within
|
* Given a rectangle, determines whether all of the tiles within
|
||||||
* the rectangle intersect an object. If the constraint parameter is
|
* the rectangle intersect an object. If the constraint parameter is
|
||||||
* non-null, the intersected objects must have that constraint.
|
* non-null, the intersected objects must have that constraint (or the
|
||||||
|
* alternate constraint, if specified).
|
||||||
*/
|
*/
|
||||||
protected boolean isCovered (Rectangle rect, ObjectData[] added,
|
protected boolean isCovered (Rectangle rect, ObjectData[] added,
|
||||||
ObjectData[] removed, String constraint)
|
ObjectData[] removed, String constraint, String altstraint)
|
||||||
{
|
{
|
||||||
ArrayList objects = getObjectData(rect, added, removed);
|
ArrayList objects = getObjectData(rect, added, removed);
|
||||||
for (int y = rect.y, ymax = rect.y + rect.height; y < ymax; y++) {
|
for (int y = rect.y, ymax = rect.y + rect.height; y < ymax; y++) {
|
||||||
@@ -343,7 +352,9 @@ public class PlacementConstraints
|
|||||||
for (int i = 0, size = objects.size(); i < size; i++) {
|
for (int i = 0, size = objects.size(); i < size; i++) {
|
||||||
ObjectData data = (ObjectData)objects.get(i);
|
ObjectData data = (ObjectData)objects.get(i);
|
||||||
if (data.bounds.contains(x, y) && (constraint == null ||
|
if (data.bounds.contains(x, y) && (constraint == null ||
|
||||||
data.tile.hasConstraint(constraint))) {
|
data.tile.hasConstraint(constraint) ||
|
||||||
|
(altstraint != null &&
|
||||||
|
data.tile.hasConstraint(altstraint)))) {
|
||||||
covered = true;
|
covered = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -389,19 +400,39 @@ public class PlacementConstraints
|
|||||||
* <code>NONE</code> if there is no such directional constraint.
|
* <code>NONE</code> if there is no such directional constraint.
|
||||||
*/
|
*/
|
||||||
protected int getConstraintDirection (ObjectData data, String prefix)
|
protected int getConstraintDirection (ObjectData data, String prefix)
|
||||||
|
{
|
||||||
|
DirectionHeight dirheight = new DirectionHeight();
|
||||||
|
return getConstraintDirectionHeight(data, prefix, dirheight) ?
|
||||||
|
dirheight.dir : NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the supplied {@link DirectionHeight} object with the direction
|
||||||
|
* and height of the constraint identified by the given prefix.
|
||||||
|
*
|
||||||
|
* @return true if the object was successfully populated, false if there is
|
||||||
|
* no such constraint
|
||||||
|
*/
|
||||||
|
protected boolean getConstraintDirectionHeight (ObjectData data,
|
||||||
|
String prefix, DirectionHeight dirheight)
|
||||||
{
|
{
|
||||||
String[] constraints = data.tile.getConstraints();
|
String[] constraints = data.tile.getConstraints();
|
||||||
if (constraints == null) {
|
if (constraints == null) {
|
||||||
return NONE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < constraints.length; i++) {
|
for (int i = 0; i < constraints.length; i++) {
|
||||||
if (constraints[i].startsWith(prefix)) {
|
if (constraints[i].startsWith(prefix)) {
|
||||||
return DirectionUtil.fromShortString(
|
int fromidx = prefix.length(),
|
||||||
constraints[i].substring(prefix.length()));
|
toidx = constraints[i].indexOf('_', fromidx);
|
||||||
|
dirheight.dir = DirectionUtil.fromShortString(toidx == -1 ?
|
||||||
|
constraints[i].substring(fromidx) :
|
||||||
|
constraints[i].substring(fromidx, toidx));
|
||||||
|
dirheight.low = constraints[i].endsWith(ObjectTileSet.LOW);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NONE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -410,7 +441,18 @@ public class PlacementConstraints
|
|||||||
*/
|
*/
|
||||||
protected String getDirectionalConstraint (String prefix, int dir)
|
protected String getDirectionalConstraint (String prefix, int dir)
|
||||||
{
|
{
|
||||||
return prefix + DirectionUtil.toShortString(dir);
|
return getDirectionalConstraint(prefix, dir, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a constraint prefix, direction, and height, returns the
|
||||||
|
* directional constraint.
|
||||||
|
*/
|
||||||
|
protected String getDirectionalConstraint (String prefix, int dir,
|
||||||
|
boolean low)
|
||||||
|
{
|
||||||
|
return prefix + DirectionUtil.toShortString(dir) +
|
||||||
|
(low ? ObjectTileSet.LOW : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -476,6 +518,13 @@ public class PlacementConstraints
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Contains the direction and height of a constraint. */
|
||||||
|
protected class DirectionHeight
|
||||||
|
{
|
||||||
|
public int dir;
|
||||||
|
public boolean low;
|
||||||
|
}
|
||||||
|
|
||||||
/** The tile manager to use for object dimensions and constraints. */
|
/** The tile manager to use for object dimensions and constraints. */
|
||||||
protected TileManager _tilemgr;
|
protected TileManager _tilemgr;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user