return false;
}
// if this is a brand new cluster, just make it 2x2 and be done
// with it
Cluster cl = clrec.getCluster();
if (cl.width == 0) {
cl.width = 2;
cl.height = 2;
// Log.info("Created new cluster for " + body.who() +
// " (" + cl + ").");
return true;
}
// Log.info("Maybe adding " + body.who() + " to " + cl + ".");
// if the cluster is already big enough, we're groovy
int target = TARGET_SIZE[clrec.size()+1];
if (cl.width >= target) {
return true;
}
// make an expanded footprint and try to fit it somewhere
int expand = target-cl.width;
Rectangle rect = null;
for (int ii = 0; ii < X_OFF.length; ii++) {
rect = new Rectangle(cl.x + expand*X_OFF[ii],
cl.y + expand*Y_OFF[ii],
cl.width+expand, cl.height+expand);
// if this rect overlaps objects, other clusters, portals or
// impassable tiles, it's no good
if (checkIntersects(_ssobj.clusters, rect, cl) ||
checkIntersects(_footprints, rect, cl) ||
checkPortals(rect) || checkViolatesPassability(rect)) {
rect = null;
} else {
break;
}
}
// if we couldn't expand in any direction, it's no go
if (rect == null) {
// Log.info("Couldn't expand cluster " + cl + ".");
return false;
}
// now look to see if we just expanded our cluster over top of any
// unsuspecting standers by and if so, attempt to subsume them
for (int bodyOid : _loners.keySet()) {
// skip ourselves
if (bodyOid == body.getOid()) {
continue;
}
// do the right thing with a person standing right on the
// cluster (they're the person we're clustering with)
Rectangle trect = _loners.get(bodyOid);
if (trect.equals(cl)) {
continue;
}
if (trect.intersects(rect)) {
// make sure this person isn't already in our cluster
ClusterObject clobj = clrec.getClusterObject();
if (clobj != null && clobj.occupants.contains(bodyOid)) {
log.warning("Ignoring stale occupant [where=" + where() +
", cluster=" + cl + ", occ=" + bodyOid + "].");
continue;
}
// make sure the subsumee exists
final BodyObject bobj = (BodyObject)_omgr.getObject(bodyOid);
if (bobj == null) {
log.warning("Can't subsume disappeared body " +
"[where=" + where() + ", cluster=" + cl +
", boid=" + bodyOid + "].");
continue;
}
// we subsume nearby pirates by queueing up their addition
// to our cluster to be processed after we finish adding
// ourselves to this cluster
final ClusterRecord fclrec = clrec;
_omgr.postRunnable(new Runnable() {
public void run () {
try {
log.info("Subsuming " + bobj.who() +
" into " + fclrec.getCluster() + ".");
fclrec.addBody(bobj);
} catch (InvocationException ie) {
log.info("Unable to subsume neighbor " +
"[cluster=" + fclrec.getCluster() +
", neighbor=" + bobj.who() +
", cause=" + ie.getMessage() + "].");
}
}
});
}
}
// Log.info("Expanding cluster [cluster=" + cl +
// ", rect=" + rect + "].");
cl.setBounds(rect);
return true;
}