redscript-mc 1.2.26 → 1.2.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -9
- package/README.zh.md +72 -4
- package/dist/__tests__/cli.test.js +13 -13
- package/dist/__tests__/optimizer-advanced.test.js +4 -4
- package/dist/__tests__/stdlib-advanced.test.js +114 -0
- package/dist/__tests__/stdlib-bigint.test.d.ts +7 -0
- package/dist/__tests__/stdlib-bigint.test.js +428 -0
- package/dist/cli.js +13 -5
- package/dist/codegen/mcfunction/index.d.ts +4 -0
- package/dist/codegen/mcfunction/index.js +9 -4
- package/dist/compile.d.ts +4 -0
- package/dist/compile.js +9 -1
- package/dist/data/arena/function/__load.mcfunction +6 -0
- package/dist/data/arena/function/__tick.mcfunction +2 -0
- package/dist/data/arena/function/announce_leaders/else_1.mcfunction +3 -0
- package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +3 -0
- package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +7 -0
- package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +4 -0
- package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +6 -0
- package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/then_0.mcfunction +4 -0
- package/dist/data/arena/function/announce_leaders.mcfunction +6 -0
- package/dist/data/arena/function/arena_tick/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/arena_tick/then_0.mcfunction +4 -0
- package/dist/data/arena/function/arena_tick.mcfunction +11 -0
- package/dist/data/counter/function/__load.mcfunction +5 -0
- package/dist/data/counter/function/__tick.mcfunction +2 -0
- package/dist/data/counter/function/counter_tick/merge_2.mcfunction +1 -0
- package/dist/data/counter/function/counter_tick/then_0.mcfunction +3 -0
- package/dist/data/counter/function/counter_tick.mcfunction +11 -0
- package/dist/data/gcd2/function/__load.mcfunction +3 -0
- package/dist/data/gcd2/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd2/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd2/function/abs.mcfunction +7 -0
- package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd2/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3/function/__load.mcfunction +3 -0
- package/dist/data/gcd3/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd3/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd3/function/abs.mcfunction +7 -0
- package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd3/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3/function/test.mcfunction +7 -0
- package/dist/data/gcd3nm/function/__load.mcfunction +3 -0
- package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd3nm/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd3nm/function/abs.mcfunction +7 -0
- package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd3nm/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3nm/function/test.mcfunction +7 -0
- package/dist/data/gcd_test/function/__load.mcfunction +3 -0
- package/dist/data/gcd_test/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd_test/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd_test/function/abs.mcfunction +7 -0
- package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd_test/function/gcd.mcfunction +14 -0
- package/dist/data/isqrttest/function/__load.mcfunction +6 -0
- package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +12 -0
- package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +5 -0
- package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +4 -0
- package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +6 -0
- package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt.mcfunction +7 -0
- package/dist/data/isqrttest/function/test.mcfunction +6 -0
- package/dist/data/mathtest/function/__load.mcfunction +3 -0
- package/dist/data/mathtest/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/mathtest/function/abs/then_0.mcfunction +5 -0
- package/dist/data/mathtest/function/abs.mcfunction +6 -0
- package/dist/data/mathtest/function/test.mcfunction +5 -0
- package/dist/data/minecraft/tags/function/load.json +5 -0
- package/dist/data/minecraft/tags/function/tick.json +5 -0
- package/dist/data/mypack/function/__load.mcfunction +13 -0
- package/dist/data/mypack/function/_atan_init.mcfunction +2 -0
- package/dist/data/mypack/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/mypack/function/abs/then_0.mcfunction +5 -0
- package/dist/data/mypack/function/abs.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +2 -0
- package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +19 -0
- package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +4 -0
- package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed.mcfunction +7 -0
- package/dist/data/mypack/function/my_game.mcfunction +10 -0
- package/dist/data/quiz/function/__load.mcfunction +16 -0
- package/dist/data/quiz/function/__tick.mcfunction +6 -0
- package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/answer_a.mcfunction +4 -0
- package/dist/data/quiz/function/answer_b.mcfunction +4 -0
- package/dist/data/quiz/function/answer_c.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/else_1.mcfunction +5 -0
- package/dist/data/quiz/function/ask_question/else_4.mcfunction +5 -0
- package/dist/data/quiz/function/ask_question/else_7.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/merge_2.mcfunction +1 -0
- package/dist/data/quiz/function/ask_question/merge_5.mcfunction +2 -0
- package/dist/data/quiz/function/ask_question/merge_8.mcfunction +2 -0
- package/dist/data/quiz/function/ask_question/then_0.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/then_3.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/then_6.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question.mcfunction +7 -0
- package/dist/data/quiz/function/finish_quiz.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/else_1.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/else_10.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_16.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_4.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_7.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +8 -0
- package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/then_0.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_12.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_15.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/then_3.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/then_6.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_9.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer.mcfunction +11 -0
- package/dist/data/quiz/function/start_quiz.mcfunction +5 -0
- package/dist/data/reqtest/function/__load.mcfunction +4 -0
- package/dist/data/reqtest/function/_table_init.mcfunction +2 -0
- package/dist/data/reqtest/function/no_trig.mcfunction +3 -0
- package/dist/data/reqtest/function/use_table.mcfunction +4 -0
- package/dist/data/reqtest2/function/__load.mcfunction +3 -0
- package/dist/data/reqtest2/function/no_trig.mcfunction +3 -0
- package/dist/data/runtime/function/__load.mcfunction +5 -0
- package/dist/data/runtime/function/__tick.mcfunction +2 -0
- package/dist/data/runtime/function/counter_tick/then_0.mcfunction +3 -0
- package/dist/data/runtime/function/counter_tick.mcfunction +13 -0
- package/dist/data/shop/function/__load.mcfunction +7 -0
- package/dist/data/shop/function/__tick.mcfunction +3 -0
- package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/else_1.mcfunction +5 -0
- package/dist/data/shop/function/complete_purchase/else_4.mcfunction +5 -0
- package/dist/data/shop/function/complete_purchase/else_7.mcfunction +3 -0
- package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/then_0.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/then_3.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/then_6.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase.mcfunction +7 -0
- package/dist/data/shop/function/handle_shop_trigger.mcfunction +3 -0
- package/dist/data/swap_test/function/__load.mcfunction +3 -0
- package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +7 -0
- package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +5 -0
- package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +3 -0
- package/dist/data/swap_test/function/gcd_old.mcfunction +8 -0
- package/dist/data/turret/function/__load.mcfunction +5 -0
- package/dist/data/turret/function/__tick.mcfunction +4 -0
- package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +4 -0
- package/dist/data/turret/function/deploy_turret.mcfunction +8 -0
- package/dist/data/turret/function/turret_tick/at_1.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/tick_body.mcfunction +3 -0
- package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +1 -0
- package/dist/data/turret/function/turret_tick.mcfunction +5 -0
- package/dist/gcd2.map.json +15 -0
- package/dist/gcd3.map.json +17 -0
- package/dist/gcd_test.map.json +15 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +11 -6
- package/dist/isqrttest.map.json +15 -0
- package/dist/lowering/index.d.ts +3 -0
- package/dist/lowering/index.js +161 -64
- package/dist/mathtest.map.json +6 -0
- package/dist/mypack.map.json +27 -0
- package/dist/optimizer/commands.d.ts +1 -0
- package/dist/optimizer/commands.js +18 -11
- package/dist/optimizer/structure.d.ts +1 -0
- package/dist/optimizer/structure.js +6 -1
- package/dist/pack.mcmeta +6 -0
- package/dist/reqtest.map.json +4 -0
- package/dist/reqtest2.map.json +4 -0
- package/dist/runtime/index.js +26 -5
- package/dist/runtime.map.json +7 -0
- package/dist/swap_test.map.json +14 -0
- package/editors/vscode/package-lock.json +3 -3
- package/editors/vscode/package.json +1 -1
- package/examples/math-showcase.mcrs +146 -0
- package/examples/readme-demo.mcrs +92 -0
- package/examples/showcase.mcrs +505 -0
- package/package.json +1 -1
- package/src/__tests__/cli.test.ts +13 -13
- package/src/__tests__/optimizer-advanced.test.ts +4 -4
- package/src/__tests__/stdlib-advanced.test.ts +120 -0
- package/src/__tests__/stdlib-bigint.test.ts +427 -0
- package/src/cli.ts +14 -5
- package/src/codegen/mcfunction/index.ts +14 -5
- package/src/compile.ts +15 -2
- package/src/index.ts +17 -7
- package/src/lowering/index.ts +165 -63
- package/src/optimizer/commands.ts +18 -12
- package/src/optimizer/structure.ts +6 -2
- package/src/runtime/index.ts +27 -5
- package/src/stdlib/advanced.mcrs +81 -0
- package/src/stdlib/bigint.mcrs +205 -0
- package/src/stdlib/math.mcrs +19 -6
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<img src="./logo.png" alt="RedScript Logo" width="64" />
|
|
4
4
|
|
|
5
|
-
<img src="https://img.shields.io/badge/RedScript-1.2-red?style=for-the-badge&logo=minecraft&logoColor=white" alt="RedScript" />
|
|
5
|
+
<img src="https://img.shields.io/badge/RedScript-1.2.27-red?style=for-the-badge&logo=minecraft&logoColor=white" alt="RedScript" />
|
|
6
6
|
|
|
7
7
|
**A typed scripting language that compiles to Minecraft datapacks.**
|
|
8
8
|
|
|
9
9
|
Write clean game logic. RedScript handles the scoreboard spaghetti.
|
|
10
10
|
|
|
11
11
|
[](https://github.com/bkmashiro/redscript/actions/workflows/ci.yml)
|
|
12
|
-
[](https://github.com/bkmashiro/redscript)
|
|
13
13
|
[](https://www.npmjs.com/package/redscript-mc)
|
|
14
14
|
[](https://www.npmjs.com/package/redscript-mc)
|
|
15
15
|
[](https://marketplace.visualstudio.com/items?itemName=bkmashiro.redscript-vscode)
|
|
@@ -76,7 +76,7 @@ fn stop() {
|
|
|
76
76
|
|
|
77
77
|
---
|
|
78
78
|
|
|
79
|
-
### What's New in v1.2
|
|
79
|
+
### What's New in v1.2.25
|
|
80
80
|
|
|
81
81
|
- `impl` blocks and methods for object-style APIs on structs
|
|
82
82
|
- `is` type narrowing for safer entity checks
|
|
@@ -275,14 +275,48 @@ redscript validate <file> Validate MC commands
|
|
|
275
275
|
|
|
276
276
|
### Standard Library
|
|
277
277
|
|
|
278
|
+
All stdlib files use `module library;` — only the functions you actually call are compiled in.
|
|
279
|
+
|
|
278
280
|
```rs
|
|
279
|
-
import "stdlib/math.mcrs" // abs, min, max, clamp
|
|
281
|
+
import "stdlib/math.mcrs" // abs, sign, min, max, clamp, lerp, isqrt, sqrt_fixed,
|
|
282
|
+
// pow_int, gcd, lcm, sin_fixed, cos_fixed, map, ceil_div,
|
|
283
|
+
// log2_int, mulfix, divfix, smoothstep, smootherstep
|
|
284
|
+
|
|
285
|
+
import "stdlib/vec.mcrs" // dot2d, cross2d, length2d_fixed, distance2d_fixed,
|
|
286
|
+
// manhattan, chebyshev, atan2_fixed, normalize2d_x/y,
|
|
287
|
+
// rotate2d_x/y, lerp2d_x/y, dot3d, cross3d_x/y/z,
|
|
288
|
+
// length3d_fixed
|
|
289
|
+
|
|
290
|
+
import "stdlib/advanced.mcrs" // fib, is_prime, collatz_steps, digit_sum, reverse_int,
|
|
291
|
+
// mod_pow, hash_int, noise1d, bezier_quad,
|
|
292
|
+
// mandelbrot_iter, julia_iter, angle_between,
|
|
293
|
+
// clamp_circle_x/y, newton_sqrt, digital_root
|
|
294
|
+
|
|
295
|
+
import "stdlib/bigint.mcrs" // bigint_init, bigint_from_int_a/b, bigint_add/sub/mul,
|
|
296
|
+
// bigint_compare, bigint_mul_small, bigint_fib
|
|
297
|
+
// — up to 32 decimal digits, runs on MC scoreboard
|
|
298
|
+
|
|
280
299
|
import "stdlib/player.mcrs" // is_alive, in_range, get_health
|
|
281
300
|
import "stdlib/timer.mcrs" // start_timer, tick_timer, has_elapsed
|
|
282
301
|
import "stdlib/cooldown.mcrs" // set_cooldown, check_cooldown
|
|
283
302
|
import "stdlib/mobs.mcrs" // ZOMBIE, SKELETON, CREEPER, ... (60+ constants)
|
|
284
303
|
```
|
|
285
304
|
|
|
305
|
+
**Example — computing Fibonacci(50) in-game:**
|
|
306
|
+
|
|
307
|
+
```rs
|
|
308
|
+
import "stdlib/bigint.mcrs"
|
|
309
|
+
|
|
310
|
+
fn show_fib() {
|
|
311
|
+
bigint_fib(50);
|
|
312
|
+
// F(50) = 12,586,269,025 — too big for int32, stored across 3 limbs:
|
|
313
|
+
let l0: int = bigint_get_a(0); // 9025
|
|
314
|
+
let l1: int = bigint_get_a(1); // 8626
|
|
315
|
+
let l2: int = bigint_get_a(2); // 125
|
|
316
|
+
say(f"F(50) limbs: {l2} {l1} {l0}");
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
286
320
|
---
|
|
287
321
|
|
|
288
322
|
### Further Reading
|
|
@@ -298,16 +332,51 @@ import "stdlib/mobs.mcrs" // ZOMBIE, SKELETON, CREEPER, ... (60+ constants
|
|
|
298
332
|
|
|
299
333
|
---
|
|
300
334
|
|
|
335
|
+
### What's New in v1.2.27
|
|
336
|
+
|
|
337
|
+
- **BigInt confirmed working in real Minecraft** (`bigint.mcrs`): arbitrary precision integers on MC scoreboard + NBT — base 10,000 × 8 limbs = up to 32 decimal digits; `bigint_add`, `bigint_sub`, `bigint_compare`, `bigint_mul`, `bigint_fib(50)` = 12,586,269,025 all verified on Paper 1.21.4
|
|
338
|
+
- **`storage_set_int` macro fix**: dynamic NBT array writes now use `execute store result storage` instead of `data modify set value $(n)` — avoids a silent Minecraft macro substitution bug with integer values
|
|
339
|
+
- **Full stdlib** (`math.mcrs`, `vec.mcrs`, `advanced.mcrs`, `bigint.mcrs`, `showcase.mcrs`): 18 math functions, 14 vector geometry functions, 20+ advanced number-theory and fractal functions
|
|
340
|
+
- **`module library;` pragma**: tree-shaking for library files — stdlib never bloats your pack
|
|
341
|
+
- **`storage_get_int` / `storage_set_int` builtins**: dynamic NBT int array read/write with runtime indices via MC 1.20.2+ macro sub-functions
|
|
342
|
+
- **`@require_on_load(fn)` decorator**: declarative load-time dependency tracking for sin/cos/atan table initializers
|
|
343
|
+
|
|
344
|
+
### What's New in v1.2.26
|
|
345
|
+
|
|
346
|
+
- **Math stdlib** (`math.mcrs`): 18 fixed-point functions — `abs`, `sign`, `min`, `max`, `clamp`, `lerp`, `isqrt`, `sqrt_fixed`, `pow_int`, `gcd`, `lcm`, `sin_fixed`, `cos_fixed`, `map`, `ceil_div`, `log2_int`, `mulfix`, `divfix`, `smoothstep`, `smootherstep`
|
|
347
|
+
- **Vector stdlib** (`vec.mcrs`): 2D and 3D geometry — dot/cross products, `length2d_fixed`, `atan2_fixed` (binary search, O(log 46)), `normalize2d`, `rotate2d`, `lerp2d`, full 3D cross product
|
|
348
|
+
- **Advanced stdlib** (`advanced.mcrs`): number theory (`fib`, `is_prime`, `collatz_steps`, `gcd`, `mod_pow`), hash/noise (`hash_int` splitmix32, `noise1d`), curves (`bezier_quad`), fractals (`mandelbrot_iter`, `julia_iter`), geometry experiments
|
|
349
|
+
- **BigInt** (`bigint.mcrs`): arbitrary precision integers — base 10,000 × 8 limbs = up to 32 decimal digits; `bigint_add/sub/compare/mul/fib` running on MC scoreboard + NBT storage
|
|
350
|
+
- **Compiler fixes**: `isqrt` large-number convergence, optimizer copy propagation alias invalidation, cross-function variable collision, MCRuntime array-index regex
|
|
351
|
+
|
|
301
352
|
### Changelog Highlights
|
|
302
353
|
|
|
354
|
+
#### v1.2.27 (2026-03-14)
|
|
355
|
+
|
|
356
|
+
- **BigInt real-MC fix**: `storage_set_int` macro now uses `execute store result storage` instead of `data modify set value $(n)` — avoids a Minecraft macro substitution bug with integer values; BigInt confirmed working on Paper 1.21.4
|
|
357
|
+
- **showcase**: `atan2_fixed` returns degrees (0–360), not millidegrees; fixed over-division in examples; `mod_pow` test cases use small safe-range moduli (no INT32 overflow)
|
|
358
|
+
|
|
359
|
+
#### v1.2.26 (2026-03-14)
|
|
360
|
+
|
|
361
|
+
- Full math/vector/advanced/bigint standard library (see above)
|
|
362
|
+
- `module library;` pragma for zero-cost tree-shaking
|
|
363
|
+
- `storage_get_int` / `storage_set_int` dynamic NBT array builtins
|
|
364
|
+
- Compiler bug fixes: `isqrt` convergence, copy propagation, variable scoping
|
|
365
|
+
|
|
366
|
+
#### v1.2.25 (2026-03-13)
|
|
367
|
+
|
|
368
|
+
- Entity type hierarchy with `W_IMPOSSIBLE_AS` warnings
|
|
369
|
+
- Variable name mangling (`$a`, `$b`, `$c`, ...) for minimal scoreboard footprint
|
|
370
|
+
- Automated CI/CD: npm publish + VSCode extension on every push
|
|
371
|
+
|
|
303
372
|
#### v1.2.0
|
|
304
373
|
|
|
305
|
-
-
|
|
306
|
-
-
|
|
307
|
-
-
|
|
308
|
-
-
|
|
374
|
+
- `impl` blocks, methods, and static constructors
|
|
375
|
+
- `is` type narrowing for entity-safe control flow
|
|
376
|
+
- `@on(Event)` static events and callback scheduling builtins
|
|
377
|
+
- Runtime f-strings for output functions
|
|
309
378
|
- Expanded stdlib with Timer OOP APIs and 313 MC tag constants
|
|
310
|
-
-
|
|
379
|
+
- Dead code elimination
|
|
311
380
|
|
|
312
381
|
See [CHANGELOG.md](./CHANGELOG.md) for the full release notes.
|
|
313
382
|
|
package/README.zh.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<img src="./logo.png" alt="RedScript Logo" width="64" />
|
|
4
4
|
|
|
5
|
-
<img src="https://img.shields.io/badge/RedScript-1.2-red?style=for-the-badge&logo=minecraft&logoColor=white" alt="RedScript" />
|
|
5
|
+
<img src="https://img.shields.io/badge/RedScript-1.2.27-red?style=for-the-badge&logo=minecraft&logoColor=white" alt="RedScript" />
|
|
6
6
|
|
|
7
7
|
**一个编译到 Minecraft Datapack 的类型化脚本语言。**
|
|
8
8
|
|
|
9
9
|
写干净的游戏逻辑,把记分板的面条代码交给 RedScript 处理。
|
|
10
10
|
|
|
11
11
|
[](https://github.com/bkmashiro/redscript/actions/workflows/ci.yml)
|
|
12
|
-
[](https://github.com/bkmashiro/redscript)
|
|
13
13
|
[](https://www.npmjs.com/package/redscript-mc)
|
|
14
14
|
[](https://www.npmjs.com/package/redscript-mc)
|
|
15
15
|
[](https://marketplace.visualstudio.com/items?itemName=bkmashiro.redscript-vscode)
|
|
@@ -73,7 +73,23 @@ let running: bool = false;
|
|
|
73
73
|
|
|
74
74
|
---
|
|
75
75
|
|
|
76
|
-
### v1.2 新增内容
|
|
76
|
+
### v1.2.27 新增内容
|
|
77
|
+
|
|
78
|
+
- **BigInt 实机验证通过** (`bigint.mcrs`):任意精度整数在 MC 记分板 + NBT 上完整运行 — base 10000 × 8 limbs = 最多 32 位十进制数;`bigint_fib(50)` = 12,586,269,025 在 Paper 1.21.4 实机验证正确
|
|
79
|
+
- **`storage_set_int` 宏修复**:动态 NBT 数组写入改用 `execute store result storage` 而非 `data modify set value $(n)` — 规避 Minecraft 宏机制对整数值的静默替换 bug
|
|
80
|
+
- **完整标准库** (`math.mcrs`、`vec.mcrs`、`advanced.mcrs`、`bigint.mcrs`、`showcase.mcrs`):18 个数学函数、14 个向量几何函数、20+ 数论与分形函数
|
|
81
|
+
- **`module library;` pragma**:库文件零成本树摇 — 标准库永远不会撑大你的数据包
|
|
82
|
+
- **`@require_on_load(fn)` 装饰器**:sin/cos/atan 查找表初始化器的声明式加载依赖跟踪
|
|
83
|
+
|
|
84
|
+
### v1.2.26 新增内容
|
|
85
|
+
|
|
86
|
+
- **数学标准库** (`math.mcrs`):18 个定点数函数 — `abs`、`sign`、`min`、`max`、`clamp`、`lerp`、`isqrt`、`sqrt_fixed`、`pow_int`、`gcd`、`lcm`、`sin_fixed`、`cos_fixed`、`map`、`ceil_div`、`log2_int`、`mulfix`、`divfix`、`smoothstep`、`smootherstep`
|
|
87
|
+
- **向量标准库** (`vec.mcrs`):2D / 3D 几何 — 点积/叉积、`length2d_fixed`、`atan2_fixed`(二分搜索正切表,O(log 46))、`normalize2d`、`rotate2d`、`lerp2d`、完整 3D 叉积
|
|
88
|
+
- **高级标准库** (`advanced.mcrs`):数论(`fib`、`is_prime`、`collatz_steps`、`mod_pow`)、哈希/噪声(splitmix32 `hash_int`、`noise1d`)、曲线(`bezier_quad`)、分形(`mandelbrot_iter`、`julia_iter`)、几何实验
|
|
89
|
+
- **BigInt** (`bigint.mcrs`):任意精度整数架构设计 — base 10000 × 8 limbs = 最多 32 位十进制数
|
|
90
|
+
- **编译器修复**:`isqrt` 大数收敛、优化器拷贝传播别名失效、跨函数变量命名冲突、MCRuntime 数组索引正则
|
|
91
|
+
|
|
92
|
+
### v1.2.25 新增内容
|
|
77
93
|
|
|
78
94
|
- `impl` 块与方法,支持围绕结构体构建面向对象风格 API
|
|
79
95
|
- `is` 类型收窄,实体判断更安全
|
|
@@ -268,14 +284,48 @@ redscript validate <file> 验证 MC 命令语法
|
|
|
268
284
|
|
|
269
285
|
### 标准库
|
|
270
286
|
|
|
287
|
+
所有标准库文件都使用 `module library;` —— 只有你实际调用的函数才会编译进去。
|
|
288
|
+
|
|
271
289
|
```rs
|
|
272
|
-
import "stdlib/math.mcrs" // abs, min, max, clamp
|
|
290
|
+
import "stdlib/math.mcrs" // abs, sign, min, max, clamp, lerp, isqrt, sqrt_fixed,
|
|
291
|
+
// pow_int, gcd, lcm, sin_fixed, cos_fixed, map, ceil_div,
|
|
292
|
+
// log2_int, mulfix, divfix, smoothstep, smootherstep
|
|
293
|
+
|
|
294
|
+
import "stdlib/vec.mcrs" // dot2d, cross2d, length2d_fixed, distance2d_fixed,
|
|
295
|
+
// manhattan, chebyshev, atan2_fixed, normalize2d_x/y,
|
|
296
|
+
// rotate2d_x/y, lerp2d_x/y, dot3d, cross3d_x/y/z,
|
|
297
|
+
// length3d_fixed
|
|
298
|
+
|
|
299
|
+
import "stdlib/advanced.mcrs" // fib, is_prime, collatz_steps, digit_sum, reverse_int,
|
|
300
|
+
// mod_pow, hash_int, noise1d, bezier_quad,
|
|
301
|
+
// mandelbrot_iter, julia_iter, angle_between,
|
|
302
|
+
// clamp_circle_x/y, newton_sqrt, digital_root
|
|
303
|
+
|
|
304
|
+
import "stdlib/bigint.mcrs" // bigint_init, bigint_from_int_a/b, bigint_add/sub/mul,
|
|
305
|
+
// bigint_compare, bigint_mul_small, bigint_fib
|
|
306
|
+
// — 最多 32 位十进制数,纯记分板运行
|
|
307
|
+
|
|
273
308
|
import "stdlib/player.mcrs" // is_alive, in_range, get_health
|
|
274
309
|
import "stdlib/timer.mcrs" // start_timer, tick_timer, has_elapsed
|
|
275
310
|
import "stdlib/cooldown.mcrs" // set_cooldown, check_cooldown
|
|
276
311
|
import "stdlib/mobs.mcrs" // ZOMBIE, SKELETON, CREEPER ... (60+ 实体常量)
|
|
277
312
|
```
|
|
278
313
|
|
|
314
|
+
**示例 — 游戏内计算斐波那契数列第 50 项:**
|
|
315
|
+
|
|
316
|
+
```rs
|
|
317
|
+
import "stdlib/bigint.mcrs"
|
|
318
|
+
|
|
319
|
+
fn show_fib() {
|
|
320
|
+
bigint_fib(50);
|
|
321
|
+
// F(50) = 12,586,269,025 — 超过 int32,分 3 个 limb 存储:
|
|
322
|
+
let l0: int = bigint_get_a(0); // 9025
|
|
323
|
+
let l1: int = bigint_get_a(1); // 8626
|
|
324
|
+
let l2: int = bigint_get_a(2); // 125
|
|
325
|
+
say(f"F(50) limbs: {l2} {l1} {l0}");
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
279
329
|
---
|
|
280
330
|
|
|
281
331
|
### 更多文档
|
|
@@ -293,6 +343,24 @@ import "stdlib/mobs.mcrs" // ZOMBIE, SKELETON, CREEPER ... (60+ 实体常
|
|
|
293
343
|
|
|
294
344
|
### 更新日志亮点
|
|
295
345
|
|
|
346
|
+
#### v1.2.27(2026-03-14)
|
|
347
|
+
|
|
348
|
+
- **BigInt 实机修复**:`storage_set_int` 宏改用 `execute store result storage`,规避 MC 宏整数替换 bug;BigInt 在 Paper 1.21.4 实机验证通过
|
|
349
|
+
- showcase 示例修复:`atan2_fixed` 返回度数(0–360),更正不必要的除以 1000;`mod_pow` 测试改用小 modulus 避免 INT32 溢出
|
|
350
|
+
|
|
351
|
+
#### v1.2.26(2026-03-14)
|
|
352
|
+
|
|
353
|
+
- 完整的数学/向量/高级/BigInt 标准库(详见上方)
|
|
354
|
+
- `module library;` pragma,实现零成本树摇
|
|
355
|
+
- `storage_get_int` / `storage_set_int` 动态 NBT 数组内置函数
|
|
356
|
+
- 编译器修复:`isqrt` 收敛、拷贝传播、变量作用域命名
|
|
357
|
+
|
|
358
|
+
#### v1.2.25(2026-03-13)
|
|
359
|
+
|
|
360
|
+
- 实体类型层级与 `W_IMPOSSIBLE_AS` 警告
|
|
361
|
+
- 变量名混淆(`$a`、`$b`、`$c` ...),最小化记分板占用
|
|
362
|
+
- CI/CD 自动化:每次推送自动发布 npm + VSCode 插件
|
|
363
|
+
|
|
296
364
|
#### v1.2.0
|
|
297
365
|
|
|
298
366
|
- 新增 `impl` 块、实例方法与静态构造函数
|
|
@@ -77,7 +77,7 @@ describe('CLI API', () => {
|
|
|
77
77
|
const source = fs.readFileSync(mainPath, 'utf-8');
|
|
78
78
|
const result = (0, index_1.compile)(source, { namespace: 'mygame', filePath: mainPath });
|
|
79
79
|
const tickTimer = result.files.find(file => file.path.endsWith('/tick_timer.mcfunction'));
|
|
80
|
-
expect(tickTimer?.content).toContain('scoreboard players set #rs
|
|
80
|
+
expect(tickTimer?.content).toContain('scoreboard players set #rs mygame.timer_ticks 1');
|
|
81
81
|
});
|
|
82
82
|
it('adds a call-site hash for stdlib internal scoreboard objectives', () => {
|
|
83
83
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-stdlib-hash-'));
|
|
@@ -106,7 +106,7 @@ describe('CLI API', () => {
|
|
|
106
106
|
const timerFns = result.files.filter(file => /timer_start__callsite_[0-9a-f]{4}\.mcfunction$/.test(file.path));
|
|
107
107
|
expect(timerFns).toHaveLength(2);
|
|
108
108
|
const objectives = timerFns
|
|
109
|
-
.flatMap(file => [...file.content.matchAll(/
|
|
109
|
+
.flatMap(file => [...file.content.matchAll(/mygame\._timer_([0-9a-f]{4})/g)].map(match => match[0]));
|
|
110
110
|
expect(new Set(objectives).size).toBe(2);
|
|
111
111
|
});
|
|
112
112
|
it('Timer::new creates timer', () => {
|
|
@@ -125,8 +125,8 @@ describe('CLI API', () => {
|
|
|
125
125
|
const result = (0, index_1.compile)(source, { namespace: 'timernew', filePath: mainPath });
|
|
126
126
|
expect(result.typeErrors).toEqual([]);
|
|
127
127
|
const newFn = result.files.find(file => file.path.endsWith('/Timer_new.mcfunction'));
|
|
128
|
-
expect(newFn?.content).toContain('scoreboard players set timer_ticks
|
|
129
|
-
expect(newFn?.content).toContain('scoreboard players set timer_active
|
|
128
|
+
expect(newFn?.content).toContain('scoreboard players set timer_ticks timernew 0');
|
|
129
|
+
expect(newFn?.content).toContain('scoreboard players set timer_active timernew 0');
|
|
130
130
|
});
|
|
131
131
|
it('Timer.start/pause/reset', () => {
|
|
132
132
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-timer-state-'));
|
|
@@ -149,9 +149,9 @@ describe('CLI API', () => {
|
|
|
149
149
|
const startFn = result.files.find(file => file.path.endsWith('/Timer_start.mcfunction'));
|
|
150
150
|
const pauseFn = result.files.find(file => file.path.endsWith('/Timer_pause.mcfunction'));
|
|
151
151
|
const resetFn = result.files.find(file => file.path.endsWith('/Timer_reset.mcfunction'));
|
|
152
|
-
expect(startFn?.content).toContain('scoreboard players set timer_active
|
|
153
|
-
expect(pauseFn?.content).toContain('scoreboard players set timer_active
|
|
154
|
-
expect(resetFn?.content).toContain('scoreboard players set timer_ticks
|
|
152
|
+
expect(startFn?.content).toContain('scoreboard players set timer_active timerstate 1');
|
|
153
|
+
expect(pauseFn?.content).toContain('scoreboard players set timer_active timerstate 0');
|
|
154
|
+
expect(resetFn?.content).toContain('scoreboard players set timer_ticks timerstate 0');
|
|
155
155
|
});
|
|
156
156
|
it('Timer.done returns bool', () => {
|
|
157
157
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-timer-done-'));
|
|
@@ -174,9 +174,9 @@ describe('CLI API', () => {
|
|
|
174
174
|
expect(result.typeErrors).toEqual([]);
|
|
175
175
|
const doneFn = result.files.find(file => file.path.endsWith('/Timer_done.mcfunction'));
|
|
176
176
|
const mainFn = result.files.find(file => file.path.endsWith('/main.mcfunction'));
|
|
177
|
-
expect(doneFn?.content).toContain('scoreboard players get timer_ticks
|
|
177
|
+
expect(doneFn?.content).toContain('scoreboard players get timer_ticks timerdone');
|
|
178
178
|
expect(doneFn?.content).toContain('return run scoreboard players get');
|
|
179
|
-
expect(mainFn?.content).toContain('execute if score $main_finished
|
|
179
|
+
expect(mainFn?.content).toContain('execute if score $main_finished timerdone matches 1..');
|
|
180
180
|
});
|
|
181
181
|
it('Timer.tick increments', () => {
|
|
182
182
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-timer-tick-'));
|
|
@@ -199,10 +199,10 @@ describe('CLI API', () => {
|
|
|
199
199
|
.filter(file => file.path.includes('/Timer_tick'))
|
|
200
200
|
.map(file => file.content)
|
|
201
201
|
.join('\n');
|
|
202
|
-
expect(tickOutput).toContain('scoreboard players get timer_active
|
|
203
|
-
expect(tickOutput).toContain('scoreboard players get timer_ticks
|
|
204
|
-
expect(tickOutput).toContain(' += $const_1
|
|
205
|
-
expect(tickOutput).toContain('execute store result score timer_ticks
|
|
202
|
+
expect(tickOutput).toContain('scoreboard players get timer_active timertick');
|
|
203
|
+
expect(tickOutput).toContain('scoreboard players get timer_ticks timertick');
|
|
204
|
+
expect(tickOutput).toContain(' += $const_1 timertick');
|
|
205
|
+
expect(tickOutput).toContain('execute store result score timer_ticks timertick run scoreboard players get $_');
|
|
206
206
|
});
|
|
207
207
|
});
|
|
208
208
|
describe('compile()', () => {
|
|
@@ -26,7 +26,7 @@ fn turret_tick() {
|
|
|
26
26
|
const result = (0, index_1.compile)(source, { namespace: 'test' });
|
|
27
27
|
const parent = getFileContent(result.files, 'data/test/function/turret_tick.mcfunction');
|
|
28
28
|
const loopBody = getFileContent(result.files, 'data/test/function/turret_tick/foreach_0.mcfunction');
|
|
29
|
-
const hoistedRead = 'execute store result score $_0
|
|
29
|
+
const hoistedRead = 'execute store result score $_0 test run scoreboard players get config test.turret_range';
|
|
30
30
|
const executeCall = 'execute as @e[tag=turret] run function test:turret_tick/foreach_0';
|
|
31
31
|
expect(parent).toContain(hoistedRead);
|
|
32
32
|
expect(parent.indexOf(hoistedRead)).toBeLessThan(parent.indexOf(executeCall));
|
|
@@ -48,7 +48,7 @@ fn read_twice() {
|
|
|
48
48
|
const fn = getFileContent(result.files, 'data/test/function/read_twice.mcfunction');
|
|
49
49
|
const readMatches = fn.match(/scoreboard players get @s test\.coins/g) ?? [];
|
|
50
50
|
expect(readMatches).toHaveLength(1);
|
|
51
|
-
expect(fn).toContain('scoreboard players operation $_1
|
|
51
|
+
expect(fn).toContain('scoreboard players operation $_1 test = $_0 test');
|
|
52
52
|
});
|
|
53
53
|
test('reuses duplicate arithmetic sequences', () => {
|
|
54
54
|
const source = `
|
|
@@ -63,9 +63,9 @@ fn math() {
|
|
|
63
63
|
`;
|
|
64
64
|
const result = (0, index_1.compile)(source, { namespace: 'test' });
|
|
65
65
|
const fn = getFileContent(result.files, 'data/test/function/math.mcfunction');
|
|
66
|
-
const addMatches = fn.match(/\+= \$const_2
|
|
66
|
+
const addMatches = fn.match(/\+= \$const_2 test/g) ?? [];
|
|
67
67
|
expect(addMatches).toHaveLength(1);
|
|
68
|
-
expect(fn).toContain('scoreboard players operation $_1
|
|
68
|
+
expect(fn).toContain('scoreboard players operation $_1 test = $_0 test');
|
|
69
69
|
});
|
|
70
70
|
});
|
|
71
71
|
describe('setblock batching', () => {
|
|
@@ -261,4 +261,118 @@ describe('julia_iter', () => {
|
|
|
261
261
|
expect(scoreOf(rt, 'r')).toBe(0);
|
|
262
262
|
});
|
|
263
263
|
});
|
|
264
|
+
// ─── Experiment: cross-stdlib (vec + math + advanced) ────────────────────────
|
|
265
|
+
const VEC_SRC = fs.readFileSync(path.join(__dirname, '../../src/stdlib/vec.mcrs'), 'utf-8');
|
|
266
|
+
function runAll(driver) {
|
|
267
|
+
const result = (0, compile_1.compile)(driver, {
|
|
268
|
+
namespace: 'exptest',
|
|
269
|
+
librarySources: [MATH_SRC, VEC_SRC, ADV_SRC],
|
|
270
|
+
});
|
|
271
|
+
if (!result.success)
|
|
272
|
+
throw new Error(result.error?.message ?? 'compile failed: ' + result.error?.message);
|
|
273
|
+
const rt = new runtime_1.MCRuntime('exptest');
|
|
274
|
+
for (const file of result.files ?? []) {
|
|
275
|
+
if (!file.path.endsWith('.mcfunction'))
|
|
276
|
+
continue;
|
|
277
|
+
const match = file.path.match(/data\/([^/]+)\/function\/(.+)\.mcfunction$/);
|
|
278
|
+
if (!match)
|
|
279
|
+
continue;
|
|
280
|
+
rt.loadFunction(`${match[1]}:${match[2]}`, file.content.split('\n'));
|
|
281
|
+
}
|
|
282
|
+
rt.load();
|
|
283
|
+
return rt;
|
|
284
|
+
}
|
|
285
|
+
function exp(rt, key) {
|
|
286
|
+
return rt.getScore('out', `exptest.${key}`) ?? 0;
|
|
287
|
+
}
|
|
288
|
+
describe('newton_sqrt', () => {
|
|
289
|
+
it('newton_sqrt(25) == 5', () => {
|
|
290
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", newton_sqrt(25)); }`);
|
|
291
|
+
rt.execFunction('test');
|
|
292
|
+
expect(exp(rt, 'r')).toBe(5);
|
|
293
|
+
});
|
|
294
|
+
it('newton_sqrt(100) == 10', () => {
|
|
295
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", newton_sqrt(100)); }`);
|
|
296
|
+
rt.execFunction('test');
|
|
297
|
+
expect(exp(rt, 'r')).toBe(10);
|
|
298
|
+
});
|
|
299
|
+
it('newton_sqrt(2) == 1', () => {
|
|
300
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", newton_sqrt(2)); }`);
|
|
301
|
+
rt.execFunction('test');
|
|
302
|
+
expect(exp(rt, 'r')).toBe(1);
|
|
303
|
+
});
|
|
304
|
+
it('newton_sqrt(0) == 0', () => {
|
|
305
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", newton_sqrt(0)); }`);
|
|
306
|
+
rt.execFunction('test');
|
|
307
|
+
expect(exp(rt, 'r')).toBe(0);
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
describe('digital_root', () => {
|
|
311
|
+
it('digital_root(493) == 7', () => {
|
|
312
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", digital_root(493)); }`);
|
|
313
|
+
rt.execFunction('test');
|
|
314
|
+
expect(exp(rt, 'r')).toBe(7);
|
|
315
|
+
});
|
|
316
|
+
it('digital_root(9) == 9', () => {
|
|
317
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", digital_root(9)); }`);
|
|
318
|
+
rt.execFunction('test');
|
|
319
|
+
expect(exp(rt, 'r')).toBe(9);
|
|
320
|
+
});
|
|
321
|
+
it('digital_root(0) == 0', () => {
|
|
322
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", digital_root(0)); }`);
|
|
323
|
+
rt.execFunction('test');
|
|
324
|
+
expect(exp(rt, 'r')).toBe(0);
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
describe('spiral_ring', () => {
|
|
328
|
+
it('spiral_ring(1) == 0', () => {
|
|
329
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", spiral_ring(1)); }`);
|
|
330
|
+
rt.execFunction('test');
|
|
331
|
+
expect(exp(rt, 'r')).toBe(0);
|
|
332
|
+
});
|
|
333
|
+
it('spiral_ring(9) == 1', () => {
|
|
334
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", spiral_ring(9)); }`);
|
|
335
|
+
rt.execFunction('test');
|
|
336
|
+
expect(exp(rt, 'r')).toBe(1);
|
|
337
|
+
});
|
|
338
|
+
it('spiral_ring(25) == 2', () => {
|
|
339
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", spiral_ring(25)); }`);
|
|
340
|
+
rt.execFunction('test');
|
|
341
|
+
expect(exp(rt, 'r')).toBe(2);
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
describe('clamp_circle', () => {
|
|
345
|
+
it('point inside: clamp_circle_x(3,4,10) == 3', () => {
|
|
346
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", clamp_circle_x(3, 4, 10)); }`);
|
|
347
|
+
rt.execFunction('test');
|
|
348
|
+
expect(exp(rt, 'r')).toBe(3);
|
|
349
|
+
});
|
|
350
|
+
it('point outside: clamp_circle_x(600,0,500) == 500', () => {
|
|
351
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", clamp_circle_x(600, 0, 500)); }`);
|
|
352
|
+
rt.execFunction('test');
|
|
353
|
+
expect(exp(rt, 'r')).toBe(500);
|
|
354
|
+
});
|
|
355
|
+
it('clamp_circle_y(0,600,500) == 500', () => {
|
|
356
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", clamp_circle_y(0, 600, 500)); }`);
|
|
357
|
+
rt.execFunction('test');
|
|
358
|
+
expect(exp(rt, 'r')).toBe(500);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
describe('angle_between', () => {
|
|
362
|
+
it('perpendicular vectors: angle_between(1000,0,0,1000) == 90', () => {
|
|
363
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", angle_between(1000, 0, 0, 1000)); }`);
|
|
364
|
+
rt.execFunction('test');
|
|
365
|
+
expect(exp(rt, 'r')).toBe(90);
|
|
366
|
+
});
|
|
367
|
+
it('parallel vectors: angle_between(1000,0,1000,0) == 0', () => {
|
|
368
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", angle_between(1000, 0, 1000, 0)); }`);
|
|
369
|
+
rt.execFunction('test');
|
|
370
|
+
expect(exp(rt, 'r')).toBe(0);
|
|
371
|
+
});
|
|
372
|
+
it('opposite vectors: angle_between(1000,0,-1000,0) == 180', () => {
|
|
373
|
+
const rt = runAll(`fn test() { scoreboard_set("out", "r", angle_between(1000, 0, -1000, 0)); }`);
|
|
374
|
+
rt.execFunction('test');
|
|
375
|
+
expect(exp(rt, 'r')).toBe(180);
|
|
376
|
+
});
|
|
377
|
+
});
|
|
264
378
|
//# sourceMappingURL=stdlib-advanced.test.js.map
|