diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index afcf91b9..c10c979e 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -2555,10 +2555,14 @@ living entities based on their spawn group. All categories can be preceded with `'!'` which will fetch all entities that are valid (health > 0) but not belonging to that group. Calls to `entity_list` always fetch entities from the current world that the script executes. -### `entity_area(type, cx, cy, cz, dx, dy, dz)` +### `entity_area(type, center, distance)` -Returns entities of a specified type in an area centered on `cx, cy, cz` and at most `dx, dy, dz` blocks away from -the center point. Uses the same selectors as `entities_list`. + +Returns entities of a specified type in an area centered on `center` and at most `distance` blocks away from +the center point. Uses the same `type` selectors as `entities_list`. + +`center` and `distance` can either be a triple of coordinates or three consecutive arguments for `entity_area`. `center` can +also be represented as a block, in this case the search box will be centered on the middle of the block. entity_area is simpler than `entity_selector` and runs about 20% faster, but is limited to predefined selectors and cuboid search area. diff --git a/docs/scarpet/api/Entities.md b/docs/scarpet/api/Entities.md index 009294f6..e09e97a1 100644 --- a/docs/scarpet/api/Entities.md +++ b/docs/scarpet/api/Entities.md @@ -56,10 +56,14 @@ living entities based on their spawn group. All categories can be preceded with `'!'` which will fetch all entities that are valid (health > 0) but not belonging to that group. Calls to `entity_list` always fetch entities from the current world that the script executes. -### `entity_area(type, cx, cy, cz, dx, dy, dz)` +### `entity_area(type, center, distance)` -Returns entities of a specified type in an area centered on `cx, cy, cz` and at most `dx, dy, dz` blocks away from -the center point. Uses the same selectors as `entities_list`. + +Returns entities of a specified type in an area centered on `center` and at most `distance` blocks away from +the center point. Uses the same `type` selectors as `entities_list`. + +`center` and `distance` can either be a triple of coordinates or three consecutive arguments for `entity_area`. `center` can +also be represented as a block, in this case the search box will be centered on the middle of the block. entity_area is simpler than `entity_selector` and runs about 20% faster, but is limited to predefined selectors and cuboid search area. diff --git a/src/main/java/carpet/script/api/Entities.java b/src/main/java/carpet/script/api/Entities.java index 72011a6f..e8f92b00 100644 --- a/src/main/java/carpet/script/api/Entities.java +++ b/src/main/java/carpet/script/api/Entities.java @@ -191,19 +191,20 @@ public class Entities { return (_c, _t ) -> retval; }); - expression.addLazyFunction("entity_area", 7, (c, t, lv) -> + expression.addLazyFunction("entity_area", -1, (c, t, lv) -> { - Vec3d center = new Vec3d( - NumericValue.asNumber(lv.get(1).evalValue(c)).getDouble(), - NumericValue.asNumber(lv.get(2).evalValue(c)).getDouble(), - NumericValue.asNumber(lv.get(3).evalValue(c)).getDouble() - ); - Box area = new Box(center, center).expand( - NumericValue.asNumber(lv.get(4).evalValue(c)).getDouble(), - NumericValue.asNumber(lv.get(5).evalValue(c)).getDouble(), - NumericValue.asNumber(lv.get(6).evalValue(c)).getDouble() - ); + if (lv.size()<3) throw new InternalExpressionException("'entity_area' requires entity type, center and range arguments"); String who = lv.get(0).evalValue(c).getString(); + CarpetContext cc = (CarpetContext)c; + Vector3Argument centerLocator = Vector3Argument.findIn(cc, lv, 1); + Vec3d center = centerLocator.vec; + if (centerLocator.fromBlock) center.add(0.5, 0.5, 0.5); + Vector3Argument rangeLocator = Vector3Argument.findIn(cc, lv, centerLocator.offset); + if (rangeLocator.fromBlock) + throw new InternalExpressionException("Range of 'entity_area' cannot come from a block argument"); + Vec3d range = rangeLocator.vec; + Box area = new Box(center, center).expand(range.x, range.y, range.z); + Pair, Predicate> pair = EntityValue.getPredicate(who); if (pair == null) { diff --git a/src/main/resources/assets/carpet/scripts/ai_tracker.sc b/src/main/resources/assets/carpet/scripts/ai_tracker.sc index d266bb0a..ba57d146 100644 --- a/src/main/resources/assets/carpet/scripts/ai_tracker.sc +++ b/src/main/resources/assets/carpet/scripts/ai_tracker.sc @@ -161,21 +161,55 @@ global_functions = { 'item_pickup' -> { '*' -> [ _(arg) -> _(e) -> ( - if (e~'type' == 'player', return([[],[],[]])); visuals = []; abnoxious_visuals = []; - half_width = e~'width'/2; - height = e~'height'; - __create_box(abnoxious_visuals, e, - [-1-half_width,0,-1-half_width], - [1+half_width, height,1+half_width], - 0xffff0000, 'item range', false + e_half_width = e~'width'/2; + e_height = e~'height'; + [box_from, box_to, color] = if (e~'type' == 'player', + + if ((ride = e~'mount') != null, + rpos = pos(ride)-pos(e); + r_half_width = ride~'width'/2; + r_height = ride~'height'; + [ [ + -1+min(-e_half_width, rpos:0-r_half_width), + min(0, rpos:1), + -1+min(-e_half_width, rpos:2-r_half_width) + ], [ + 1+max(e_half_width, rpos:0+r_half_width), + max(e_height, rpos:1+r_height), + 1+max(e_half_width, rpos:2+r_half_width) + ], 0xffaa0000 + ] + , + [ + [ -1-e_half_width, -0.5, -1-e_half_width ], + [ 1+e_half_width, e_height+0.5, 1+e_half_width ], + 0xffaa0000 + ] + ) + , + + [ + [ -1-e_half_width, 0, -1-e_half_width ], + [ 1+e_half_width, e_height, 1+e_half_width ], + 0xffff0000 + ] ); - [x,y,z] = pos(e); - for (filter(entity_area('item', x, y+height/2, z, 1+half_width, height/2, 1+half_width), pos(_) != pos(e)), + box_ctr = (box_from+box_to)/2; + box_range = box_ctr-box_from; + + __create_box(abnoxious_visuals, e, + box_from, + box_to, + color, 'item range', false + ); + for (filter(entity_area('item', pos(e)+box_ctr, box_range), pos(_) != pos(e)), visuals+=['line', global_duration, 'from', pos(e)+[0,1,0], 'to', pos(_)+[0,0,0], 'color', 0xffff00ff] ); - [visuals, abnoxious_visuals, []]; + + + [visuals, abnoxious_visuals, []] ), , null