redscript-mc 1.2.21 → 1.2.25
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/.github/workflows/publish-extension-on-ci.yml +100 -0
- package/dist/__tests__/entity-types.test.d.ts +1 -0
- package/dist/__tests__/entity-types.test.js +203 -0
- package/dist/__tests__/var-allocator.test.d.ts +1 -0
- package/dist/__tests__/var-allocator.test.js +69 -0
- package/dist/ast/types.d.ts +2 -1
- package/dist/cli.js +17 -6
- package/dist/codegen/mcfunction/index.d.ts +2 -0
- package/dist/codegen/mcfunction/index.js +52 -43
- package/dist/codegen/structure/index.d.ts +4 -1
- package/dist/codegen/structure/index.js +8 -12
- package/dist/codegen/var-allocator.d.ts +28 -0
- package/dist/codegen/var-allocator.js +78 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -6
- package/dist/lowering/index.d.ts +2 -0
- package/dist/lowering/index.js +62 -3
- package/dist/parser/index.js +22 -1
- package/dist/typechecker/index.js +30 -0
- package/dist/types/entity-hierarchy.d.ts +29 -0
- package/dist/types/entity-hierarchy.js +107 -0
- package/editors/vscode/package-lock.json +6 -4
- package/editors/vscode/package.json +3 -3
- package/package.json +1 -1
- package/src/__tests__/entity-types.test.ts +236 -0
- package/src/__tests__/var-allocator.test.ts +75 -0
- package/src/ast/types.ts +8 -4
- package/src/cli.ts +20 -6
- package/src/codegen/mcfunction/index.ts +60 -48
- package/src/codegen/structure/index.ts +9 -14
- package/src/codegen/var-allocator.ts +75 -0
- package/src/examples/capture_the_flag.mcrs +34 -34
- package/src/examples/hunger_games.mcrs +59 -59
- package/src/examples/new_features_demo.mcrs +32 -32
- package/src/examples/parkour_race.mcrs +58 -58
- package/src/index.ts +10 -6
- package/src/lowering/index.ts +73 -8
- package/src/parser/index.ts +20 -1
- package/src/typechecker/index.ts +30 -0
- package/src/types/entity-hierarchy.ts +120 -0
- package/dist/data/arena/function/__load.mcfunction +0 -6
- package/dist/data/arena/function/__tick.mcfunction +0 -2
- package/dist/data/arena/function/announce_leaders/else_1.mcfunction +0 -3
- package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +0 -1
- package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +0 -3
- package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +0 -7
- package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +0 -1
- package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +0 -4
- package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +0 -6
- package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +0 -1
- package/dist/data/arena/function/announce_leaders/then_0.mcfunction +0 -4
- package/dist/data/arena/function/announce_leaders.mcfunction +0 -6
- package/dist/data/arena/function/arena_tick/merge_2.mcfunction +0 -1
- package/dist/data/arena/function/arena_tick/then_0.mcfunction +0 -4
- package/dist/data/arena/function/arena_tick.mcfunction +0 -11
- package/dist/data/counter/function/__load.mcfunction +0 -5
- package/dist/data/counter/function/__tick.mcfunction +0 -2
- package/dist/data/counter/function/counter_tick/merge_2.mcfunction +0 -1
- package/dist/data/counter/function/counter_tick/then_0.mcfunction +0 -3
- package/dist/data/counter/function/counter_tick.mcfunction +0 -11
- package/dist/data/minecraft/tags/function/load.json +0 -5
- package/dist/data/minecraft/tags/function/tick.json +0 -5
- package/dist/data/quiz/function/__load.mcfunction +0 -16
- package/dist/data/quiz/function/__tick.mcfunction +0 -6
- package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +0 -4
- package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +0 -4
- package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +0 -4
- package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +0 -4
- package/dist/data/quiz/function/answer_a.mcfunction +0 -4
- package/dist/data/quiz/function/answer_b.mcfunction +0 -4
- package/dist/data/quiz/function/answer_c.mcfunction +0 -4
- package/dist/data/quiz/function/ask_question/else_1.mcfunction +0 -5
- package/dist/data/quiz/function/ask_question/else_4.mcfunction +0 -5
- package/dist/data/quiz/function/ask_question/else_7.mcfunction +0 -4
- package/dist/data/quiz/function/ask_question/merge_2.mcfunction +0 -1
- package/dist/data/quiz/function/ask_question/merge_5.mcfunction +0 -2
- package/dist/data/quiz/function/ask_question/merge_8.mcfunction +0 -2
- package/dist/data/quiz/function/ask_question/then_0.mcfunction +0 -4
- package/dist/data/quiz/function/ask_question/then_3.mcfunction +0 -4
- package/dist/data/quiz/function/ask_question/then_6.mcfunction +0 -4
- package/dist/data/quiz/function/ask_question.mcfunction +0 -7
- package/dist/data/quiz/function/finish_quiz.mcfunction +0 -6
- package/dist/data/quiz/function/handle_answer/else_1.mcfunction +0 -5
- package/dist/data/quiz/function/handle_answer/else_10.mcfunction +0 -3
- package/dist/data/quiz/function/handle_answer/else_16.mcfunction +0 -3
- package/dist/data/quiz/function/handle_answer/else_4.mcfunction +0 -3
- package/dist/data/quiz/function/handle_answer/else_7.mcfunction +0 -5
- package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +0 -2
- package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +0 -2
- package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +0 -2
- package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +0 -8
- package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +0 -2
- package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +0 -2
- package/dist/data/quiz/function/handle_answer/then_0.mcfunction +0 -5
- package/dist/data/quiz/function/handle_answer/then_12.mcfunction +0 -5
- package/dist/data/quiz/function/handle_answer/then_15.mcfunction +0 -6
- package/dist/data/quiz/function/handle_answer/then_3.mcfunction +0 -6
- package/dist/data/quiz/function/handle_answer/then_6.mcfunction +0 -5
- package/dist/data/quiz/function/handle_answer/then_9.mcfunction +0 -6
- package/dist/data/quiz/function/handle_answer.mcfunction +0 -11
- package/dist/data/quiz/function/start_quiz.mcfunction +0 -5
- package/dist/data/shop/function/__load.mcfunction +0 -7
- package/dist/data/shop/function/__tick.mcfunction +0 -3
- package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +0 -4
- package/dist/data/shop/function/complete_purchase/else_1.mcfunction +0 -5
- package/dist/data/shop/function/complete_purchase/else_4.mcfunction +0 -5
- package/dist/data/shop/function/complete_purchase/else_7.mcfunction +0 -3
- package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +0 -2
- package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +0 -2
- package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +0 -2
- package/dist/data/shop/function/complete_purchase/then_0.mcfunction +0 -4
- package/dist/data/shop/function/complete_purchase/then_3.mcfunction +0 -4
- package/dist/data/shop/function/complete_purchase/then_6.mcfunction +0 -4
- package/dist/data/shop/function/complete_purchase.mcfunction +0 -7
- package/dist/data/shop/function/handle_shop_trigger.mcfunction +0 -3
- package/dist/data/turret/function/__load.mcfunction +0 -5
- package/dist/data/turret/function/__tick.mcfunction +0 -4
- package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +0 -4
- package/dist/data/turret/function/deploy_turret.mcfunction +0 -8
- package/dist/data/turret/function/turret_tick/at_1.mcfunction +0 -2
- package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +0 -2
- package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +0 -2
- package/dist/data/turret/function/turret_tick/tick_body.mcfunction +0 -3
- package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +0 -1
- package/dist/data/turret/function/turret_tick.mcfunction +0 -5
- package/dist/pack.mcmeta +0 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ============================================
|
|
2
2
|
// Capture the Flag Mini-Game
|
|
3
3
|
// ============================================
|
|
4
|
-
//
|
|
4
|
+
// Scenario: Two teams compete, capture the enemy flag and return it to your base to score
|
|
5
5
|
// Scenario: Two teams compete to capture enemy flag
|
|
6
6
|
// ============================================
|
|
7
7
|
|
|
@@ -11,7 +11,7 @@ import "../stdlib/world.mcrs"
|
|
|
11
11
|
import "../stdlib/inventory.mcrs"
|
|
12
12
|
import "../stdlib/particles.mcrs"
|
|
13
13
|
|
|
14
|
-
// =====
|
|
14
|
+
// ===== Configuration =====
|
|
15
15
|
const RED_BASE_X: int = -50;
|
|
16
16
|
const RED_BASE_Z: int = 0;
|
|
17
17
|
const BLUE_BASE_X: int = 50;
|
|
@@ -19,7 +19,7 @@ const BLUE_BASE_Z: int = 0;
|
|
|
19
19
|
const BASE_Y: int = 64;
|
|
20
20
|
const WIN_SCORE: int = 3;
|
|
21
21
|
|
|
22
|
-
// =====
|
|
22
|
+
// ===== Game State =====
|
|
23
23
|
struct GameState {
|
|
24
24
|
running: int,
|
|
25
25
|
red_score: int,
|
|
@@ -36,54 +36,54 @@ let game: GameState = {
|
|
|
36
36
|
blue_flag_taken: 0
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
// =====
|
|
39
|
+
// ===== Initialization =====
|
|
40
40
|
@load
|
|
41
41
|
fn init() {
|
|
42
|
-
//
|
|
42
|
+
// Create scoreboards
|
|
43
43
|
scoreboard_add_objective("ctf_team", "dummy");
|
|
44
44
|
scoreboard_add_objective("ctf_flag", "dummy");
|
|
45
45
|
|
|
46
|
-
//
|
|
46
|
+
// Create teams
|
|
47
47
|
setup_two_teams();
|
|
48
48
|
|
|
49
|
-
//
|
|
49
|
+
// World settings
|
|
50
50
|
set_day();
|
|
51
51
|
weather_clear();
|
|
52
52
|
enable_keep_inventory();
|
|
53
53
|
|
|
54
|
-
announce("§e[CTF] §
|
|
54
|
+
announce("§e[CTF] §fCapture the Flag loaded! Use /trigger start to begin");
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
// =====
|
|
57
|
+
// ===== Start Game =====
|
|
58
58
|
fn start_game() {
|
|
59
59
|
game.running = 1;
|
|
60
60
|
game.red_score = 0;
|
|
61
61
|
game.blue_score = 0;
|
|
62
62
|
|
|
63
|
-
//
|
|
63
|
+
// Randomly assign teams
|
|
64
64
|
assign_teams();
|
|
65
65
|
|
|
66
|
-
//
|
|
66
|
+
// Teleport to respective bases
|
|
67
67
|
tp(@a[team=red], RED_BASE_X, BASE_Y, RED_BASE_Z);
|
|
68
68
|
tp(@a[team=blue], BLUE_BASE_X, BASE_Y, BLUE_BASE_Z);
|
|
69
69
|
|
|
70
|
-
//
|
|
70
|
+
// Give equipment
|
|
71
71
|
foreach (p in @a) {
|
|
72
72
|
clear_inventory(p);
|
|
73
73
|
give_kit_warrior(p);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
//
|
|
76
|
+
// Place flags (banners)
|
|
77
77
|
place_flags();
|
|
78
78
|
|
|
79
|
-
announce("§e[CTF] §
|
|
80
|
-
title(@a, "§
|
|
79
|
+
announce("§e[CTF] §aGame started! Capture the enemy flag!");
|
|
80
|
+
title(@a, "§6Capture the Flag - Start!");
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
fn place_flags() {
|
|
84
|
-
//
|
|
84
|
+
// Red team flag (red banner block)
|
|
85
85
|
setblock(RED_BASE_X, BASE_Y + 1, RED_BASE_Z, "minecraft:red_banner");
|
|
86
|
-
//
|
|
86
|
+
// Blue team flag
|
|
87
87
|
setblock(BLUE_BASE_X, BASE_Y + 1, BLUE_BASE_Z, "minecraft:blue_banner");
|
|
88
88
|
|
|
89
89
|
game.red_flag_taken = 0;
|
|
@@ -104,7 +104,7 @@ fn assign_teams() {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
// =====
|
|
107
|
+
// ===== Tick Check =====
|
|
108
108
|
@tick
|
|
109
109
|
fn game_tick() {
|
|
110
110
|
if (game.running == 1) {
|
|
@@ -115,22 +115,22 @@ fn game_tick() {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
fn check_flag_pickup() {
|
|
118
|
-
//
|
|
118
|
+
// Check if blue team players are near the red flag
|
|
119
119
|
foreach (p in @a[team=blue]) {
|
|
120
|
-
//
|
|
120
|
+
// If near red team base and flag has not been taken
|
|
121
121
|
let dist: int = distance_to(p, RED_BASE_X, BASE_Y, RED_BASE_Z);
|
|
122
122
|
if (dist < 3) {
|
|
123
123
|
if (game.red_flag_taken == 0) {
|
|
124
124
|
game.red_flag_taken = 1;
|
|
125
125
|
tag_add(p, "has_flag");
|
|
126
126
|
setblock(RED_BASE_X, BASE_Y + 1, RED_BASE_Z, "minecraft:air");
|
|
127
|
-
announce("§e[CTF] §
|
|
127
|
+
announce("§e[CTF] §9Blue Team §fhas taken the §cRed Flag§f!");
|
|
128
128
|
glow(p, 9999);
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
//
|
|
133
|
+
// Check if red team players are near the blue flag
|
|
134
134
|
foreach (p in @a[team=red]) {
|
|
135
135
|
let dist: int = distance_to(p, BLUE_BASE_X, BASE_Y, BLUE_BASE_Z);
|
|
136
136
|
if (dist < 3) {
|
|
@@ -138,7 +138,7 @@ fn check_flag_pickup() {
|
|
|
138
138
|
game.blue_flag_taken = 1;
|
|
139
139
|
tag_add(p, "has_flag");
|
|
140
140
|
setblock(BLUE_BASE_X, BASE_Y + 1, BLUE_BASE_Z, "minecraft:air");
|
|
141
|
-
announce("§e[CTF] §
|
|
141
|
+
announce("§e[CTF] §cRed Team §fhas taken the §9Blue Flag§f!");
|
|
142
142
|
glow(p, 9999);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
@@ -146,12 +146,12 @@ fn check_flag_pickup() {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
fn check_flag_capture() {
|
|
149
|
-
//
|
|
149
|
+
// Blue team carries red flag back to blue base
|
|
150
150
|
foreach (p in @a[team=blue, tag=has_flag]) {
|
|
151
151
|
let dist: int = distance_to(p, BLUE_BASE_X, BASE_Y, BLUE_BASE_Z);
|
|
152
152
|
if (dist < 5) {
|
|
153
153
|
game.blue_score = game.blue_score + 1;
|
|
154
|
-
announce("§e[CTF] §
|
|
154
|
+
announce("§e[CTF] §9Blue Team §ascores! §f(" + game.blue_score + "/" + WIN_SCORE + ")");
|
|
155
155
|
tag_remove(p, "has_flag");
|
|
156
156
|
effect_clear(p, "minecraft:glowing");
|
|
157
157
|
place_flags();
|
|
@@ -159,12 +159,12 @@ fn check_flag_capture() {
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
//
|
|
162
|
+
// Red team carries blue flag back to red base
|
|
163
163
|
foreach (p in @a[team=red, tag=has_flag]) {
|
|
164
164
|
let dist: int = distance_to(p, RED_BASE_X, BASE_Y, RED_BASE_Z);
|
|
165
165
|
if (dist < 5) {
|
|
166
166
|
game.red_score = game.red_score + 1;
|
|
167
|
-
announce("§e[CTF] §
|
|
167
|
+
announce("§e[CTF] §cRed Team §ascores! §f(" + game.red_score + "/" + WIN_SCORE + ")");
|
|
168
168
|
tag_remove(p, "has_flag");
|
|
169
169
|
effect_clear(p, "minecraft:glowing");
|
|
170
170
|
place_flags();
|
|
@@ -186,23 +186,23 @@ fn end_game(winner: string) {
|
|
|
186
186
|
game.running = 0;
|
|
187
187
|
|
|
188
188
|
if (winner == "red") {
|
|
189
|
-
title(@a, "§
|
|
190
|
-
announce("§e[CTF] §
|
|
189
|
+
title(@a, "§cRed Team Wins!");
|
|
190
|
+
announce("§e[CTF] §cRed Team §6wins the match!");
|
|
191
191
|
} else {
|
|
192
|
-
title(@a, "§
|
|
193
|
-
announce("§e[CTF] §
|
|
192
|
+
title(@a, "§9Blue Team Wins!");
|
|
193
|
+
announce("§e[CTF] §9Blue Team §6wins the match!");
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
//
|
|
196
|
+
// Cleanup
|
|
197
197
|
foreach (p in @a[tag=has_flag]) {
|
|
198
198
|
tag_remove(p, "has_flag");
|
|
199
199
|
effect_clear(p);
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
// =====
|
|
203
|
+
// ===== Helper Functions =====
|
|
204
204
|
fn distance_to(target: selector, x: int, y: int, z: int) -> int {
|
|
205
|
-
//
|
|
205
|
+
// Simplified distance calculation (using scoreboard)
|
|
206
206
|
let dist: int = scoreboard_get(target, "ctf_dist");
|
|
207
207
|
return dist;
|
|
208
208
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// ============================================
|
|
2
|
-
// Hunger Games -
|
|
2
|
+
// Hunger Games - Hunger Games
|
|
3
3
|
// ============================================
|
|
4
|
-
//
|
|
5
|
-
//
|
|
4
|
+
// Scenario: Players start from the central supply point, scavenge for resources
|
|
5
|
+
// Border gradually shrinks, last survivor wins
|
|
6
6
|
// Scenario: Battle royale with shrinking border
|
|
7
7
|
// ============================================
|
|
8
8
|
|
|
@@ -11,19 +11,19 @@ import "../stdlib/world.mcrs"
|
|
|
11
11
|
import "../stdlib/bossbar.mcrs"
|
|
12
12
|
import "../stdlib/particles.mcrs"
|
|
13
13
|
|
|
14
|
-
// =====
|
|
14
|
+
// ===== Configuration =====
|
|
15
15
|
const CENTER_X: int = 0;
|
|
16
16
|
const CENTER_Y: int = 64;
|
|
17
17
|
const CENTER_Z: int = 0;
|
|
18
18
|
const INITIAL_BORDER: int = 200;
|
|
19
19
|
const FINAL_BORDER: int = 20;
|
|
20
|
-
const GRACE_PERIOD: int = 600; // 30
|
|
21
|
-
const SHRINK_INTERVAL: int = 1200; //
|
|
20
|
+
const GRACE_PERIOD: int = 600; // 30-second grace period
|
|
21
|
+
const SHRINK_INTERVAL: int = 1200; // Shrink every 60 seconds
|
|
22
22
|
|
|
23
|
-
// =====
|
|
23
|
+
// ===== Game State =====
|
|
24
24
|
struct HGState {
|
|
25
25
|
running: int,
|
|
26
|
-
phase: int, // 0
|
|
26
|
+
phase: int, // 0=waiting, 1=countdown, 2=in-game, 3=ended
|
|
27
27
|
countdown: int,
|
|
28
28
|
grace_timer: int,
|
|
29
29
|
border_timer: int,
|
|
@@ -46,36 +46,36 @@ fn init() {
|
|
|
46
46
|
scoreboard_add_objective("hg_kills", "dummy");
|
|
47
47
|
scoreboard_add_objective("hg_alive", "dummy");
|
|
48
48
|
|
|
49
|
-
//
|
|
49
|
+
// Set world border
|
|
50
50
|
// worldborder center 0 0
|
|
51
51
|
// worldborder set 200
|
|
52
52
|
|
|
53
|
-
announce("§c[
|
|
53
|
+
announce("§c[Hunger Games] §fLoaded! Waiting for players to join...");
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
// =====
|
|
56
|
+
// ===== Start Game =====
|
|
57
57
|
fn start_countdown() {
|
|
58
58
|
game.phase = 1;
|
|
59
|
-
game.countdown = 200; // 10
|
|
59
|
+
game.countdown = 200; // 10-second countdown
|
|
60
60
|
|
|
61
|
-
//
|
|
61
|
+
// Teleport all players to center
|
|
62
62
|
foreach (p in @a) {
|
|
63
|
-
tp(p, CENTER_X, CENTER_Y + 50, CENTER_Z); //
|
|
63
|
+
tp(p, CENTER_X, CENTER_Y + 50, CENTER_Z); // Start from high altitude
|
|
64
64
|
scoreboard_set(p, "hg_kills", 0);
|
|
65
65
|
scoreboard_set(p, "hg_alive", 1);
|
|
66
66
|
|
|
67
|
-
//
|
|
67
|
+
// Clear inventory
|
|
68
68
|
clear(p);
|
|
69
69
|
|
|
70
|
-
//
|
|
70
|
+
// Freeze players
|
|
71
71
|
effect(p, "minecraft:slowness", 15, 255);
|
|
72
|
-
effect(p, "minecraft:jump_boost", 15, 250); //
|
|
72
|
+
effect(p, "minecraft:jump_boost", 15, 250); // Prevent jumping
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
//
|
|
76
|
-
create_progress_bar("hg_border", "§
|
|
75
|
+
// Create border bossbar
|
|
76
|
+
create_progress_bar("hg_border", "§cBorder Shrinking", INITIAL_BORDER);
|
|
77
77
|
|
|
78
|
-
announce("§c[
|
|
78
|
+
announce("§c[Hunger Games] §eGame starting soon!");
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
fn start_game() {
|
|
@@ -85,25 +85,25 @@ fn start_game() {
|
|
|
85
85
|
game.border_timer = SHRINK_INTERVAL;
|
|
86
86
|
game.current_border = INITIAL_BORDER;
|
|
87
87
|
|
|
88
|
-
//
|
|
88
|
+
// Count alive players
|
|
89
89
|
game.alive_count = 0;
|
|
90
90
|
foreach (p in @a) {
|
|
91
91
|
game.alive_count = game.alive_count + 1;
|
|
92
92
|
|
|
93
|
-
//
|
|
93
|
+
// Clear effects
|
|
94
94
|
effect_clear(p);
|
|
95
95
|
|
|
96
|
-
//
|
|
96
|
+
// Slow fall
|
|
97
97
|
slow_fall(p, 100);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
title(@a, "§
|
|
101
|
-
subtitle(@a, "§
|
|
100
|
+
title(@a, "§cGame Start!");
|
|
101
|
+
subtitle(@a, "§7Scavenge for supplies, be the last survivor!");
|
|
102
102
|
|
|
103
|
-
announce("§c[
|
|
103
|
+
announce("§c[Hunger Games] §aGame started! §7No PvP for 30 seconds");
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
// =====
|
|
106
|
+
// ===== Every Tick =====
|
|
107
107
|
@tick
|
|
108
108
|
fn game_tick() {
|
|
109
109
|
if (game.phase == 1) {
|
|
@@ -118,7 +118,7 @@ fn game_tick() {
|
|
|
118
118
|
fn countdown_tick() {
|
|
119
119
|
game.countdown = game.countdown - 1;
|
|
120
120
|
|
|
121
|
-
//
|
|
121
|
+
// Countdown hints
|
|
122
122
|
if (game.countdown == 100) {
|
|
123
123
|
title(@a, "§e5");
|
|
124
124
|
playsound("minecraft:block.note_block.pling", "player", @a);
|
|
@@ -146,30 +146,30 @@ fn countdown_tick() {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
fn main_game_tick() {
|
|
149
|
-
//
|
|
149
|
+
// Grace period
|
|
150
150
|
if (game.grace_timer > 0) {
|
|
151
151
|
game.grace_timer = game.grace_timer - 1;
|
|
152
152
|
|
|
153
153
|
if (game.grace_timer == 0) {
|
|
154
|
-
announce("§c[
|
|
155
|
-
title(@a, "§
|
|
154
|
+
announce("§c[Hunger Games] §4Grace period ended! Combat is now allowed!");
|
|
155
|
+
title(@a, "§cCombat Start!");
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
//
|
|
159
|
+
// Border shrink
|
|
160
160
|
game.border_timer = game.border_timer - 1;
|
|
161
161
|
if (game.border_timer <= 0) {
|
|
162
162
|
shrink_border();
|
|
163
163
|
game.border_timer = SHRINK_INTERVAL;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
//
|
|
166
|
+
// Update bossbar
|
|
167
167
|
update_bar("hg_border", game.current_border);
|
|
168
168
|
|
|
169
|
-
//
|
|
169
|
+
// Check border damage
|
|
170
170
|
check_border_damage();
|
|
171
171
|
|
|
172
|
-
//
|
|
172
|
+
// Check alive count
|
|
173
173
|
check_alive();
|
|
174
174
|
}
|
|
175
175
|
|
|
@@ -182,13 +182,13 @@ fn shrink_border() {
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
// worldborder set game.current_border 60
|
|
185
|
-
announce("§c[
|
|
185
|
+
announce("§c[Hunger Games] §eBorder is shrinking! Current size: " + game.current_border);
|
|
186
186
|
|
|
187
|
-
//
|
|
187
|
+
// Update bossbar
|
|
188
188
|
bossbar_set_max("hg_border", INITIAL_BORDER);
|
|
189
189
|
bossbar_set_value("hg_border", game.current_border);
|
|
190
190
|
|
|
191
|
-
//
|
|
191
|
+
// Color change
|
|
192
192
|
if (game.current_border < 50) {
|
|
193
193
|
bossbar_set_color("hg_border", "red");
|
|
194
194
|
} else {
|
|
@@ -200,12 +200,12 @@ fn shrink_border() {
|
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
fn check_border_damage() {
|
|
203
|
-
//
|
|
204
|
-
//
|
|
203
|
+
// Deal damage to players outside the border
|
|
204
|
+
// Need to check if player is outside the border
|
|
205
205
|
foreach (p in @a) {
|
|
206
|
-
//
|
|
206
|
+
// Simplified: using execute positioned
|
|
207
207
|
let _dist: int = 0; // TODO: calculate distance from center
|
|
208
|
-
//
|
|
208
|
+
// If outside border, deal damage
|
|
209
209
|
// effect(p, "minecraft:wither", 1, 0);
|
|
210
210
|
}
|
|
211
211
|
}
|
|
@@ -224,15 +224,15 @@ fn check_alive() {
|
|
|
224
224
|
|
|
225
225
|
game.alive_count = alive;
|
|
226
226
|
|
|
227
|
-
//
|
|
228
|
-
actionbar(@a, "§
|
|
227
|
+
// Update scoreboard display
|
|
228
|
+
actionbar(@a, "§cAlive: " + alive);
|
|
229
229
|
|
|
230
|
-
//
|
|
230
|
+
// Check for victory
|
|
231
231
|
if (alive <= 1) {
|
|
232
232
|
if (alive == 1) {
|
|
233
233
|
declare_winner(winner);
|
|
234
234
|
} else {
|
|
235
|
-
//
|
|
235
|
+
// No survivors
|
|
236
236
|
end_game_no_winner();
|
|
237
237
|
}
|
|
238
238
|
}
|
|
@@ -244,11 +244,11 @@ fn declare_winner(winner: selector) {
|
|
|
244
244
|
|
|
245
245
|
let kills: int = scoreboard_get(winner, "hg_kills");
|
|
246
246
|
|
|
247
|
-
title(@a, "§
|
|
248
|
-
announce("§c[
|
|
249
|
-
announce("§
|
|
247
|
+
title(@a, "§6Winner!");
|
|
248
|
+
announce("§c[Hunger Games] §6Game Over!");
|
|
249
|
+
announce("§aWinner's kills: " + kills);
|
|
250
250
|
|
|
251
|
-
//
|
|
251
|
+
// Victory effects
|
|
252
252
|
totem_effect(winner);
|
|
253
253
|
buff_all(winner, 200);
|
|
254
254
|
|
|
@@ -259,27 +259,27 @@ fn end_game_no_winner() {
|
|
|
259
259
|
game.phase = 3;
|
|
260
260
|
game.running = 0;
|
|
261
261
|
|
|
262
|
-
title(@a, "§
|
|
263
|
-
subtitle(@a, "§
|
|
262
|
+
title(@a, "§7Game Over");
|
|
263
|
+
subtitle(@a, "§cNo survivors");
|
|
264
264
|
|
|
265
265
|
remove_bar("hg_border");
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
-
// =====
|
|
268
|
+
// ===== Player Death Handler =====
|
|
269
269
|
fn on_player_death(player: selector, killer: selector) {
|
|
270
270
|
scoreboard_set(player, "hg_alive", 0);
|
|
271
271
|
|
|
272
|
-
//
|
|
272
|
+
// Update kill count
|
|
273
273
|
scoreboard_add(killer, "hg_kills", 1);
|
|
274
274
|
|
|
275
|
-
//
|
|
275
|
+
// Switch to spectator mode
|
|
276
276
|
// gamemode spectator player
|
|
277
277
|
|
|
278
278
|
let kills: int = scoreboard_get(killer, "hg_kills");
|
|
279
|
-
announce("§c☠ §
|
|
279
|
+
announce("§c☠ §7A player was eliminated! Killer now has " + kills + " kills");
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
-
// =====
|
|
282
|
+
// ===== Reset Game =====
|
|
283
283
|
fn reset_game() {
|
|
284
284
|
game.phase = 0;
|
|
285
285
|
game.running = 0;
|
|
@@ -291,11 +291,11 @@ fn reset_game() {
|
|
|
291
291
|
// gamemode survival p
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
//
|
|
294
|
+
// Reset border
|
|
295
295
|
game.current_border = INITIAL_BORDER;
|
|
296
296
|
// worldborder set 200
|
|
297
297
|
|
|
298
298
|
remove_bar("hg_border");
|
|
299
299
|
|
|
300
|
-
announce("§c[
|
|
300
|
+
announce("§c[Hunger Games] §7Game has been reset");
|
|
301
301
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* RedScript New Features Demo
|
|
3
|
-
*
|
|
3
|
+
* Showcasing language features added on 2026-03-12
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// ============================================
|
|
7
|
-
// 1.
|
|
7
|
+
// 1. Type Inference
|
|
8
8
|
// ============================================
|
|
9
9
|
fn type_inference_demo() {
|
|
10
|
-
//
|
|
10
|
+
// No need to write `: int`, compiler infers automatically
|
|
11
11
|
let health = 100;
|
|
12
12
|
let name = "Steve";
|
|
13
13
|
let alive = true;
|
|
14
14
|
let speed = 1.5;
|
|
15
15
|
|
|
16
|
-
// NBT
|
|
16
|
+
// NBT suffixes can also be inferred
|
|
17
17
|
let damage = 20b; // byte
|
|
18
18
|
let distance = 1000s; // short
|
|
19
19
|
let bignum = 999999L; // long
|
|
@@ -23,25 +23,25 @@ fn type_inference_demo() {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// ============================================
|
|
26
|
-
// 2.
|
|
26
|
+
// 2. For-Range Loops
|
|
27
27
|
// ============================================
|
|
28
28
|
fn for_range_demo() {
|
|
29
|
-
//
|
|
29
|
+
// Loop from 0 to 9
|
|
30
30
|
for i in 0..10 {
|
|
31
31
|
say("Count: ${i}");
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
//
|
|
34
|
+
// Can be used for countdown
|
|
35
35
|
for sec in 0..5 {
|
|
36
36
|
title(@a, "Starting in ${sec}...");
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
// ============================================
|
|
41
|
-
// 3. NBT
|
|
41
|
+
// 3. NBT Structured Params
|
|
42
42
|
// ============================================
|
|
43
43
|
fn nbt_params_demo() {
|
|
44
|
-
//
|
|
44
|
+
// Give item with NBT
|
|
45
45
|
give(@s, "minecraft:diamond_sword", 1, {
|
|
46
46
|
display: { Name: "Excalibur" },
|
|
47
47
|
Enchantments: [
|
|
@@ -50,7 +50,7 @@ fn nbt_params_demo() {
|
|
|
50
50
|
]
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
//
|
|
53
|
+
// Summon entity with attributes
|
|
54
54
|
summon("minecraft:zombie", @s, {
|
|
55
55
|
CustomName: "Boss Zombie",
|
|
56
56
|
Health: 100.0,
|
|
@@ -61,31 +61,31 @@ fn nbt_params_demo() {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
// ============================================
|
|
64
|
-
// 4. Set
|
|
64
|
+
// 4. Set Data Structure (Runtime Set)
|
|
65
65
|
// ============================================
|
|
66
66
|
fn set_demo() {
|
|
67
|
-
//
|
|
67
|
+
// Create set
|
|
68
68
|
let visited = set_new();
|
|
69
69
|
|
|
70
|
-
//
|
|
70
|
+
// Add elements using method syntax
|
|
71
71
|
visited.add("spawn");
|
|
72
72
|
visited.add("castle");
|
|
73
73
|
visited.add("dungeon");
|
|
74
74
|
|
|
75
|
-
//
|
|
75
|
+
// Check if exists
|
|
76
76
|
if (visited.contains("castle")) {
|
|
77
77
|
say("You've been to the castle!");
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
//
|
|
80
|
+
// Remove element
|
|
81
81
|
visited.remove("spawn");
|
|
82
82
|
|
|
83
|
-
//
|
|
83
|
+
// Clear set
|
|
84
84
|
visited.clear();
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// ============================================
|
|
88
|
-
// 5.
|
|
88
|
+
// 5. Method Syntax Sugar
|
|
89
89
|
// ============================================
|
|
90
90
|
fn method_syntax_demo() {
|
|
91
91
|
let items: string[] = [];
|
|
@@ -98,7 +98,7 @@ fn method_syntax_demo() {
|
|
|
98
98
|
let count = items.len();
|
|
99
99
|
say("You have ${count} items");
|
|
100
100
|
|
|
101
|
-
//
|
|
101
|
+
// Sets can also use method syntax
|
|
102
102
|
let tags = set_new();
|
|
103
103
|
tags.add("vip");
|
|
104
104
|
tags.add("admin");
|
|
@@ -109,44 +109,44 @@ fn method_syntax_demo() {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// ============================================
|
|
112
|
-
// 6. #mc_name
|
|
112
|
+
// 6. #mc_name Syntax (MC Identifier Syntax)
|
|
113
113
|
// ============================================
|
|
114
114
|
fn mc_name_demo() {
|
|
115
|
-
// #name
|
|
115
|
+
// #name compiles to bare MC name (without quotes)
|
|
116
116
|
scoreboard_set(@s, #kills, 0);
|
|
117
117
|
scoreboard_add(@s, #deaths, 1);
|
|
118
118
|
|
|
119
119
|
let score = scoreboard_get(@s, #points);
|
|
120
120
|
|
|
121
|
-
//
|
|
121
|
+
// For tag
|
|
122
122
|
tag_add(@s, #vip);
|
|
123
123
|
|
|
124
|
-
//
|
|
124
|
+
// For team
|
|
125
125
|
team_join(@s, #red);
|
|
126
126
|
|
|
127
|
-
//
|
|
127
|
+
// Comparison: strings still need quotes
|
|
128
128
|
give(@s, "minecraft:diamond", 1);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
// ============================================
|
|
132
|
-
// 7.
|
|
132
|
+
// 7. Block Comments
|
|
133
133
|
// ============================================
|
|
134
134
|
|
|
135
135
|
/*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
136
|
+
* This is a block comment
|
|
137
|
+
* Can span multiple lines
|
|
138
138
|
*/
|
|
139
139
|
|
|
140
140
|
/**
|
|
141
|
-
*
|
|
142
|
-
* @param player
|
|
141
|
+
* This is a doc comment
|
|
142
|
+
* @param player Target player
|
|
143
143
|
*/
|
|
144
144
|
fn documented_function() {
|
|
145
145
|
say("Hello!");
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
// ============================================
|
|
149
|
-
//
|
|
149
|
+
// Combined Example: Simple Game
|
|
150
150
|
// ============================================
|
|
151
151
|
|
|
152
152
|
struct Player {
|
|
@@ -163,7 +163,7 @@ fn init_player() {
|
|
|
163
163
|
visited: visited_set
|
|
164
164
|
};
|
|
165
165
|
|
|
166
|
-
//
|
|
166
|
+
// Record spawn point (using set_add since visited is a string ID)
|
|
167
167
|
set_add(p.visited, "spawn");
|
|
168
168
|
|
|
169
169
|
scoreboard_set(@s, #score, p.score);
|
|
@@ -172,7 +172,7 @@ fn init_player() {
|
|
|
172
172
|
|
|
173
173
|
@tick(rate=20)
|
|
174
174
|
fn game_tick() {
|
|
175
|
-
//
|
|
175
|
+
// Check once per second
|
|
176
176
|
for i in 0..1 {
|
|
177
177
|
let score = scoreboard_get(@s, #score);
|
|
178
178
|
if (score >= 100) {
|
|
@@ -183,7 +183,7 @@ fn game_tick() {
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
fn reward_player(amount: int) {
|
|
186
|
-
//
|
|
186
|
+
// Type inference + NBT params
|
|
187
187
|
let bonus = amount * 2;
|
|
188
188
|
scoreboard_add(@s, #score, bonus);
|
|
189
189
|
|