poi can query in square column as well.
This commit is contained in:
1 parent
1006e0ac40
commit
81ae5bbb40
2 files changed
+36
-21
No files matched your search
@@ -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> block_data(x,y,z) => '{TransferCooldown:0,x:450,y:68, ... }'
|
||||||
</pre>
|
</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
|
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`.
|
occupancy load. With optional `type`, `radius` and `status`, returns a list of POIs around `pos` within a
|
||||||
If `status` is specified (either 'available', or 'occupied') returns only POIs with that status. The return format is
|
given `radius`. If the `type` is specified, returns only poi types of that types, or everything if omitted or `'any'`.
|
||||||
again, poi type, occupancy load, and extra tripple of coordinates.
|
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
|
The return format of the results is a list of poi type, occupancy load, and extra triple of coordinates.
|
||||||
via `poi(pos)` in only provided for completness.
|
|
||||||
|
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>
|
<pre>
|
||||||
poi(x,y,z) => null // nothing set at position
|
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.BiFunction;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static carpet.script.utils.WorldTools.canHasChunk;
|
import static carpet.script.utils.WorldTools.canHasChunk;
|
||||||
import static java.lang.Math.abs;
|
import static java.lang.Math.abs;
|
||||||
@@ -401,7 +402,7 @@ public class CarpetExpression
|
|||||||
return (c_, t_) -> retval;
|
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) ->
|
this.expr.addLazyFunction("poi", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
@@ -431,9 +432,11 @@ public class CarpetExpression
|
|||||||
);
|
);
|
||||||
return (_c, _t) -> ret;
|
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();
|
if (radius < 0) return ListValue.lazyEmpty();
|
||||||
Predicate<PointOfInterestType> condition = PointOfInterestType.ALWAYS_TRUE;
|
Predicate<PointOfInterestType> condition = PointOfInterestType.ALWAYS_TRUE;
|
||||||
|
PointOfInterestStorage.OccupationStatus status = PointOfInterestStorage.OccupationStatus.ANY;
|
||||||
|
boolean inColumn = false;
|
||||||
if (locator.offset + 1 < lv.size())
|
if (locator.offset + 1 < lv.size())
|
||||||
{
|
{
|
||||||
String poiType = lv.get(locator.offset+1).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
String poiType = lv.get(locator.offset+1).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
||||||
@@ -443,20 +446,27 @@ public class CarpetExpression
|
|||||||
if (type == PointOfInterestType.UNEMPLOYED && !"unemployed".equals(poiType)) return LazyValue.NULL;
|
if (type == PointOfInterestType.UNEMPLOYED && !"unemployed".equals(poiType)) return LazyValue.NULL;
|
||||||
condition = (tt) -> tt == type;
|
condition = (tt) -> tt == type;
|
||||||
}
|
}
|
||||||
|
if (locator.offset + 2 < lv.size())
|
||||||
|
{
|
||||||
|
String statusString = lv.get(locator.offset+2).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
||||||
|
if ("occupied".equals(statusString))
|
||||||
|
status = PointOfInterestStorage.OccupationStatus.IS_OCCUPIED;
|
||||||
|
else if ("available".equals(statusString))
|
||||||
|
status = PointOfInterestStorage.OccupationStatus.HAS_SPACE;
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PointOfInterestStorage.OccupationStatus status = PointOfInterestStorage.OccupationStatus.ANY;
|
Stream<PointOfInterest> pois = inColumn?
|
||||||
if (locator.offset + 2 < lv.size())
|
store.getInSquare(condition, pos, radius, status):
|
||||||
{
|
store.getInCircle(condition, pos, radius, status);
|
||||||
String statusString = lv.get(locator.offset+2).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
Value ret = ListValue.wrap(pois.sorted(Comparator.comparingDouble(p -> p.getPos().getSquaredDistance(pos))).map(p ->
|
||||||
if ("occupied".equals(statusString))
|
|
||||||
status = PointOfInterestStorage.OccupationStatus.IS_OCCUPIED;
|
|
||||||
else if ("available".equals(statusString))
|
|
||||||
status = PointOfInterestStorage.OccupationStatus.HAS_SPACE;
|
|
||||||
else
|
|
||||||
return LazyValue.NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value ret = ListValue.wrap(store.getInCircle(condition, pos, (int)radius, status).sorted(Comparator.comparingDouble(p -> p.getPos().getSquaredDistance(pos))).map(p ->
|
|
||||||
ListValue.of(
|
ListValue.of(
|
||||||
new StringValue(p.getType().toString()),
|
new StringValue(p.getType().toString()),
|
||||||
new NumericValue(p.getType().getTicketCount() - ((PointOfInterest_scarpetMixin)p).getFreeTickets()),
|
new NumericValue(p.getType().getTicketCount() - ((PointOfInterest_scarpetMixin)p).getFreeTickets()),
|
||||||
|
|||||||
Reference in new issue
Block a user