poi can query in square column as well.

This commit is contained in:
gnembon committed 2020-09-07 01:26:23 -03:00
1 parent 1006e0ac40
commit 81ae5bbb40
2 files changed
+29 -14

No files matched your search

+11 -6
View File
@@ -261,15 +261,20 @@ used to match specific information from it, or use it to copy to another block
<pre> block_data(x,y,z) => '{TransferCooldown:0,x:450,y:68, ... }'
</pre>
### `poi(pos), poi(pos, radius), poi(pos, radius, status)`
### `poi(pos), poi(pos, radius?, type?, status?, column?)`
Queries a POI (Point of Interest) at a given position, returning `null` if none is found, or tuple of poi type and its
occupancy load. With optional `radius` and `status`, returns a list of POIs around `pos` within a given `radius`.
If `status` is specified (either 'available', or 'occupied') returns only POIs with that status. The return format is
again, poi type, occupancy load, and extra tripple of coordinates.
occupancy load. With optional `type`, `radius` and `status`, returns a list of POIs around `pos` within a
given `radius`. If the `type` is specified, returns only poi types of that types, or everything if omitted or `'any'`.
If `status` is specified (either `'any'`, `'available'`, or `'occupied'`) returns only POIs with that status.
With `column` set to `true`, it will return all POIs in a cuboid with `radius` blocks away on x and z, in the entire
block column from 0 to 255. Default (`false`) returns POIs within a spherical area centered on `pos` and with `radius`
radius.
Querying for POIs using the radius is intended use of POI mechanics and ability of accessing individual POIs
via `poi(pos)` in only provided for completness.
The return format of the results is a list of poi type, occupancy load, and extra triple of coordinates.
Querying for POIs using the radius is the intended use of POI mechanics, and the ability of accessing individual POIs
via `poi(pos)` in only provided for completeness.
<pre>
poi(x,y,z) => null // nothing set at position
@@ -164,6 +164,7 @@ import java.util.concurrent.CompletionException;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static carpet.script.utils.WorldTools.canHasChunk;
import static java.lang.Math.abs;
@@ -401,7 +402,7 @@ public class CarpetExpression
return (c_, t_) -> retval;
});
// poi_get(pos, radius?, type?, occupation?)
// poi_get(pos, radius?, type?, occupation?, column_mode?)
this.expr.addLazyFunction("poi", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext) c;
@@ -431,9 +432,11 @@ public class CarpetExpression
);
return (_c, _t) -> ret;
}
long radius = NumericValue.asNumber(lv.get(locator.offset+0).evalValue(c)).getLong();
int radius = NumericValue.asNumber(lv.get(locator.offset+0).evalValue(c)).getInt();
if (radius < 0) return ListValue.lazyEmpty();
Predicate<PointOfInterestType> condition = PointOfInterestType.ALWAYS_TRUE;
PointOfInterestStorage.OccupationStatus status = PointOfInterestStorage.OccupationStatus.ANY;
boolean inColumn = false;
if (locator.offset + 1 < lv.size())
{
String poiType = lv.get(locator.offset+1).evalValue(c).getString().toLowerCase(Locale.ROOT);
@@ -443,8 +446,6 @@ public class CarpetExpression
if (type == PointOfInterestType.UNEMPLOYED && !"unemployed".equals(poiType)) return LazyValue.NULL;
condition = (tt) -> tt == type;
}
}
PointOfInterestStorage.OccupationStatus status = PointOfInterestStorage.OccupationStatus.ANY;
if (locator.offset + 2 < lv.size())
{
String statusString = lv.get(locator.offset+2).evalValue(c).getString().toLowerCase(Locale.ROOT);
@@ -452,11 +453,20 @@ public class CarpetExpression
status = PointOfInterestStorage.OccupationStatus.IS_OCCUPIED;
else if ("available".equals(statusString))
status = PointOfInterestStorage.OccupationStatus.HAS_SPACE;
else
return LazyValue.NULL;
else if (!("any".equals(statusString)))
throw new InternalExpressionException(
"Incorrect POI occupation status "+status+ " use `any`, " + "`occupied` or `available`"
);
if (locator.offset + 3 < lv.size())
{
inColumn = lv.get(locator.offset+3).evalValue(c, Context.BOOLEAN).getBoolean();
}
Value ret = ListValue.wrap(store.getInCircle(condition, pos, (int)radius, status).sorted(Comparator.comparingDouble(p -> p.getPos().getSquaredDistance(pos))).map(p ->
}
}
Stream<PointOfInterest> pois = inColumn?
store.getInSquare(condition, pos, radius, status):
store.getInCircle(condition, pos, radius, status);
Value ret = ListValue.wrap(pois.sorted(Comparator.comparingDouble(p -> p.getPos().getSquaredDistance(pos))).map(p ->
ListValue.of(
new StringValue(p.getType().toString()),
new NumericValue(p.getType().getTicketCount() - ((PointOfInterest_scarpetMixin)p).getFreeTickets()),