├── .gitignore ├── README.md ├── README_en.md ├── __pycache__ ├── consts.cpython-312.pyc └── logger.cpython-312.pyc ├── basic_1.20.zip ├── basic_1.20 ├── data │ ├── basic │ │ └── functions │ │ │ ├── array │ │ │ ├── add.mcfunction │ │ │ ├── add │ │ │ │ ├── macro.mcfunction │ │ │ │ └── repeat.mcfunction │ │ │ ├── execute.mcfunction │ │ │ └── member │ │ │ │ ├── execute.mcfunction │ │ │ │ └── macro.mcfunction │ │ │ ├── byte │ │ │ └── execute.mcfunction │ │ │ ├── double │ │ │ ├── convert │ │ │ │ ├── 4.mcfunction │ │ │ │ └── execute.mcfunction │ │ │ └── execute.mcfunction │ │ │ ├── float │ │ │ ├── convert │ │ │ │ ├── 4.mcfunction │ │ │ │ └── execute.mcfunction │ │ │ └── execute.mcfunction │ │ │ ├── get_type_score.mcfunction │ │ │ ├── int │ │ │ ├── convert.mcfunction │ │ │ ├── convert │ │ │ │ ├── 4.mcfunction │ │ │ │ └── execute.mcfunction │ │ │ └── execute.mcfunction │ │ │ ├── load.mcfunction │ │ │ ├── operation.mcfunction │ │ │ └── string │ │ │ ├── add.mcfunction │ │ │ └── execute.mcfunction │ └── minecraft │ │ └── tags │ │ └── functions │ │ └── load.json └── pack.mcmeta ├── basic_1.21.zip ├── basic_1.21 ├── data │ ├── basic │ │ └── function │ │ │ ├── array │ │ │ ├── add.mcfunction │ │ │ ├── add │ │ │ │ ├── macro.mcfunction │ │ │ │ └── repeat.mcfunction │ │ │ ├── execute.mcfunction │ │ │ └── member │ │ │ │ ├── execute.mcfunction │ │ │ │ └── macro.mcfunction │ │ │ ├── byte │ │ │ └── execute.mcfunction │ │ │ ├── double │ │ │ ├── convert │ │ │ │ ├── 4.mcfunction │ │ │ │ └── execute.mcfunction │ │ │ └── execute.mcfunction │ │ │ ├── float │ │ │ ├── convert │ │ │ │ ├── 4.mcfunction │ │ │ │ └── execute.mcfunction │ │ │ └── execute.mcfunction │ │ │ ├── get_type_score.mcfunction │ │ │ ├── int │ │ │ ├── convert.mcfunction │ │ │ ├── convert │ │ │ │ ├── 4.mcfunction │ │ │ │ └── execute.mcfunction │ │ │ └── execute.mcfunction │ │ │ ├── load.mcfunction │ │ │ ├── operation.mcfunction │ │ │ └── string │ │ │ ├── add.mcfunction │ │ │ └── execute.mcfunction │ └── minecraft │ │ └── tags │ │ └── function │ │ └── load.json └── pack.mcmeta ├── built_in_function.py ├── calc.py ├── consts.py ├── docs └── index.html ├── example ├── animation.planet ├── health_bar.planet ├── test.planet ├── test2.planet ├── test3.planet └── test_.planet ├── grammer.lark ├── log.md ├── logger.py ├── new_compiler.py ├── requirements.txt ├── rpg_planet ├── blocks.planet ├── camera.planet ├── id.planet ├── main.planet ├── main_display.planet ├── mob │ ├── health_bar.planet │ ├── mob.planet │ ├── summon.planet │ └── test.planet ├── skill.planet ├── skills.planet └── stat.planet ├── transform.py └── web ├── image ├── file.svg ├── folder.svg ├── global.svg ├── namespace.svg ├── output.svg └── version.svg ├── index.html └── style.css /.gitignore: -------------------------------------------------------------------------------- 1 | compiler.spec 2 | new_compiler.spec 3 | /build 4 | /dist 5 | /etc 6 | /pack 7 | /rpg 8 | /napolitan 9 | /temp 10 | /40planet_area 11 | /rpg_datapack 12 | /skill 13 | /minecraft_problem 14 | /health_bar 15 | /rpg 몹 모델링들 16 | /village-wildwest 17 | /village-test 18 | /rpg_mob 19 | /rpg_mob_datapack 20 | /bdengine 21 | /40planet_ani 22 | /40planet_mawang_ani 23 | /maz 24 | 40planet_ani.zip 25 | new_compiler.exe 26 | __pycache__/ 27 | .venv -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Datapack-Compiler 2 | 이 프로젝트는 마인크래프트 컴파일러를 만드는 프로젝트입니다. 3 | 40행성(40planet)에 의해 제작되었으며, 출처만 표기한다면 자유로운 사용을 허가합니다. 4 | 5 | If you are english speaker, check out [README_en.md](https://github.com/alexmonkey05/Datapack-Compiler/blob/main/README_en.md)! 6 | 7 | - [사용법](#사용법) 8 | - [Vscode 문법 강조 확장](#vscode-문법-강조-확장) 9 | - [기여](#기여) 10 | - [문법](#문법) 11 | - [일반](#일반) 12 | - [execute](#execute) 13 | - [import](#import) 14 | - [내장 함수](#내장-함수) 15 | 16 | # 사용법 17 | 영상 튜토리얼이 있습니다! [Comet Tutorial](https://youtu.be/vzlmWR5MqCY)을 참고하세요. 18 | 19 | ## 설치 및 실행 20 | ### 컴파일 버전 사용 (Windows 한정) 21 | 1. [Release 탭](https://github.com/alexmonkey05/Datapack-Compiler/releases)에서 `compiler.exe`를 다운로드합니다. 22 | 1. 실행에는 두 가지 방법이 있습니다. `compiler.exe`를 실행할 경우, GUI 모드로 진입하며, `compiler.exe --cli `를 입력해 실행할 경우, CLI 모드로 진입합니다. 23 | 24 | #### 인자 (CLI 모드) 25 | | 인자 | 설명 | 26 | | ---- | ---- | 27 | | `--cli` | GUI 모드 대신 CLI 모드를 사용합니다. | 28 | | `-p ` or `--planet` | 컴파일 할 파일을 지정합니다. | 29 | | `-v ` or `--version` | 컴파일에 사용할 마인크래프트 버전을 지정합니다. | 30 | | `-d ` or `--dist` | 결과물이 위치할 폴더를 지정합니다. | 31 | | `-n ` or `--name` | 네임스페이스를 입력합니다. (기본값=`pack`) | 32 | | `-l` or `--logger` | 출력될 로그의 레벨을 정합니다. (기본값=`INFO`) (`DEBUG` > `INFO` > `WARNING` > `ERROR` > `CRITICAL` > `FATAL` > `LOG` 순으로 레벨이 높습니다.) | 33 | | `-h` or `--help` | 도움말 페이지를 표시합니다. | 34 | 35 | #### 예제 (CLI 모드) 36 | ``` 37 | compiler.exe --cli --planet ./a.planet --version 1.21 --dist ./world/datapacks --name packpack --logger DEBUG 38 | ``` 39 | ``` 40 | compiler.exe --cli -p ./a.planet -v 1.21 -d ./world/datapacks -n packpack -l DEBUG 41 | ``` 42 | 43 | ### 프로젝트 코드 사용 (Windows, macOS, Linux) 44 | 1. [Release 탭](https://github.com/alexmonkey05/Datapack-Compiler/releases)에서 프로젝트 코드를 다운로드합니다. 45 | 1. `cd <프로젝트 경로>`를 실행합니다. 46 | 1. `pip install -r requirements.txt`를 실행합니다. 이 작업은 필요한 패키지를 자동으로 설치합니다.\ 47 | **[Warning]** 만약, Windows 유저가 아닐경우, `sudo apt-get install python3-tk` 명령어를 입력해야 할 수도 있습니다. 48 | 1. `python new_compiler.py`(Windows) 또는 `python3 new_compiler.py`(유니버설)를 실행합니다. 실행 시 GUI 모드로 진입합니다. 49 | 50 | ## GUI 모드 51 | | 52 | :----: | :----: 53 | 컴파일 성공 시 | 컴파일 실패 시 54 | 55 | - 네임스페이스는 소문자만 입력받습니다. 기본값은 `pack`입니다. 56 | - `컴파일` 버튼을 눌러 코드를 컴파일합니다. 57 | - 마인크래프트 세이브파일의 `datapacks` 폴더에 생성된 데이터팩과 `basic_1.20.zip` 또는 `basic_1.21.zip`을 넣어줍니다. 58 | - 이제 마인크래프트에 접속해 `/reload`를 실행해 데이터팩을 새로고침하면 실행됩니다. 59 | 60 | # Vscode 문법 강조 확장 61 | [Comet Highlighter(VSC Marketplace Link)](https://marketplace.visualstudio.com/items?itemName=alexmonkey05.comet-highlighter) 62 | 위의 링크로 들어가거나 VSCode를 실행 후 extensions에서 Comet Highlighter를 검색해 다운로드 하여 사용할 수 있습니다 63 | 해당 익스텐션은 색만 표시해줄 뿐, 자동완성 기능은 없습니다 64 | 65 | # 기여 66 | - exe 파일을 이 명령어를 통해 생성할 수 있습니다. 67 | ``` 68 | pyinstaller --noconfirm --onefile --console --add-data "\grammer.lark;." --add-data "\web;web/" "\new_compiler.py" 69 | ``` 70 | 71 | # 문법 72 | ## 일반 73 | ### 자료형 목록 74 | - int 75 | - `1`, `-2`, `100`과 같은 정수 자료형 76 | - float, double 77 | - `1.0`, `3.14`와 같은 소수 자료형 78 | - string 79 | - `"This is string"`과 같은 문자열 자료형 80 | - nbt 81 | - `{id:"minecraft:block_display",Tags:["temp"]}`와 같은 json 자료형 82 | ### 변수 선언 83 | `var <변수명>`의 형태로 선언한다 84 | ``` 85 | var a 86 | var b = 2.0 87 | var c = "asdf" 88 | ``` 89 | 90 | 배열 선언은 다른 변수와 똑같이 선언한다 91 | ``` 92 | var array = [1, 2, 3] 93 | ``` 94 | ### 지역변수 95 | ``` 96 | var a 97 | if (조건) { 98 | var a 99 | } 100 | ``` 101 | 이때, if문 안의 a와 밖의 a는 서로 다른 변수이다. 102 | 또한, if문 안에서는 a가 선언 되었으므로 밖의 a에 접근하지 못한다 103 | ### 줄바꿈 104 | `\n` 또는 `;`를 명령어의 끝으로 생각한다 105 | - 단, `[`, `{` 등의 몇몇 예외가 있다 106 | ``` 107 | var a 108 | var b = { 109 | test: "asdf" 110 | } 111 | ``` 112 | 113 | ``` 114 | var a; 115 | var b = { 116 | test: "asdf" 117 | }; 118 | ``` 119 | ### 연산 120 | 괄호 > 멤버 > 산술 > 관계(부등식) > 논리(and, or) > 대입 순으로 연산이 진행된다 121 | - 괄호 122 | - `()` 123 | - 멤버(배열의 원소에 접근하는 연산) 124 | - `[]` 125 | - 산술 126 | - `+` 127 | - `-` 128 | - `*` 129 | - `/` 130 | - `%` 131 | - `double`과 `float`의 경우, 소수점 아래 2자리까지만 값이 보존된다. 더 정확한 값을 얻고 싶다면 `divide`와 `multiply` 함수를 사용하는 것이 좋다. 132 | - 관계 133 | - `==` 134 | - `!=` 135 | - `<=` 136 | - `>=` 137 | - `<` 138 | - `>` 139 | - 논리 140 | - `and` 141 | - `or` 142 | - `!` 143 | - 대입 144 | - `=` 145 | 만약 연산의 피연산자들의 자료형이 서로 다른 경우, 에러가 발생한다 146 | 단, `double`과 `float`, `int`의 경우엔 에러가 나지 않는다 147 | ``` 148 | 1 + "1" 149 | ``` 150 | 151 | ``` 152 | Runtime Error: Operand must have same type 153 | ``` 154 | 연산의 결과는 연산자의 뒤쪽 피연산자를 따라갑니다 155 | ex) 0.3 * 1 = 0 156 | `!`의 경우, `!(is_module())`와 같이 뒤에 괄호를 넣어야 한다 157 | 달리 말하자면 함수처럼 써야 한다는 소리이다 158 | ### 조건문 159 | `if( <조건> ){ ~~~ }`와 같은 형식으로 작성한다 160 | 중괄호를 생략하는 경우, 조건 다음의 명령어 한 줄만 실행한다. 161 | ``` 162 | var a = 0; 163 | if(a == 0){ 164 | a = a + 1; 165 | } 166 | ``` 167 | 168 | ``` 169 | var a = 0 170 | if(a == 0) 171 | a = a + 1 172 | ``` 173 | `if (...) {...} else {...}`과 같은 형태로 else를 사용할 수 있다 174 | 마찬가지로 중괄호를 생략하는 경우, 한 줄의 명령어만 실행된다 175 | ``` 176 | var a = 0 177 | if(a == 1){ 178 | a = a + 1 179 | } else { 180 | a = a - 1 181 | } 182 | ``` 183 | 184 | ``` 185 | var a = 0 186 | if(a == 1){ 187 | a = a + 1 188 | } else 189 | a = a - 1 190 | ``` 191 | 중괄호를 생략하면 다음 한 줄의 명령어만 실행하기 때문에 `else if` 구문도 지원한다 192 | 그러나 종종 else if를 사용하는 경우 버그가 발생할 수 있으니 되도록 중괄호를 쓰는 것을 권장한다 193 | ``` 194 | var a = 0 195 | if(a == 1){ 196 | a = a + 1 197 | } else if (a == 0){ 198 | a = a + 2 199 | } 200 | ``` 201 | 조건 안에 연산 없이 변수만 넣어도 된다 202 | ``` 203 | var a = 1 204 | if(a){ # true 205 | print(a) 206 | } 207 | ``` 208 | 이때, 참/거짓을 판단하는 기준은 마인크래프트의 `execute store` 구문을 따른다 209 | 때문애 다음과 같은 값이 들어가는 경우, 거짓이 나올 수 있다 210 | - "" (빈 문자열) 211 | - 0.4 (반올림 했을 때 0이 되는 소수) 212 | - -1 (음수) 213 | - [] (빈 배열) 214 | ### 반복문 215 | `while`의 경우, `if`와 같은 형태로 적을 수 있다 216 | ``` 217 | var a = 0 218 | while(a < 10){ 219 | a = a + 1 220 | } 221 | ``` 222 | 223 | ``` 224 | var a = 0 225 | while(a < 10) 226 | a = a + 1 227 | ``` 228 | `break` 키워드를 통해 루프를 멈출 수 있다 229 | `continue`와 `for`는 지원하지 않는다 230 | 231 | ### 함수 선언 232 | `def <함수명>( [매개변수] ){...}`의 형태로 적어 함수를 선언할 수 있다 233 | `[매개변수]`는 필요에 따라 생략해도 된다 234 | ``` 235 | def tick(){ 236 | var a = 1 237 | } 238 | ``` 239 | 240 | ``` 241 | def test(var a, var b){ 242 | print(a, b) 243 | } 244 | ``` 245 | 함수 이름에 대문자를 사용하면 마인크래프트는 그 함수를 그냥 없는 것으로 생각한다 246 | ~~멍청이이다~~ 247 | 그러니 함수명에 대문자를 쓰지 않도록 하자 248 | 249 | - `def tick`을 통해 tick이라는 이름의 함수를 선언한 경우, 이 함수는 매틱 실행된다 250 | - `def load`을 통해 load이라는 이름의 함수를 선언한 경우, 이 함수는 맵이 로딩될 때 1회 실행된다 251 | - 이렇게 실행되는 `load`와 `tick`은 인수를 받을 수 없다 252 | ### 함수 호출 253 | `함수명(인자)`와 같이 작성하여 함수를 호출 할 수 있다 254 | ``` 255 | def wa(var a){ 256 | return "sans" 257 | } 258 | 259 | def load(){ 260 | wa(3) 261 | } 262 | ``` 263 | 만약 `/function`명령어를 사용해 함수를 호출하고 싶다면 아래와 같이 쓰면 된다 264 | 이때, 인자는 가장 최근에 사용된 인자를 한번 더 사용한다 265 | ``` 266 | def dumb_function(var a){ 267 | return a 268 | } 269 | 270 | /function __namespace__:dumb_function 271 | ``` 272 | `__namespace__`는 사용자가 입력한 네임스페이스로 바뀐다 273 | 만약 모듈로서 `import` 되었다면 `__namespace__`는 `namespace:filename/`의 형식으로 바뀌므로 걱정할 필요 없다 274 | ### 마인크래프트 명령어 275 | `/`를 맨 앞에 쓰면 그것은 마인크래프트 명령어로 인식한다 276 | ``` 277 | /say a 278 | /gamemode creative @a 279 | ``` 280 | 281 | 커맨드의 시작에 `$`를 적고, `$(변수명)`처럼 적으면 매크로처럼 사용 가능하다 282 | ``` 283 | var a = 123 284 | /$say $(a) 285 | var command = "say a" 286 | /$$(command) 287 | ``` 288 | 289 | ``` 290 | [@] 123 291 | [@] a 292 | ``` 293 | 294 | ### 주석 295 | `#` 또는 `/#`을 사용해 주석을 달 수 있다 296 | ``` 297 | # 데이터팩에 적히지 않는 주석 298 | /# 데이터팩에 적히는 주석 299 | ``` 300 | ~~사실 `/#`이 필요할까 하긴 싶은데 일단 적어봤습니다~~ 301 | 302 | ## import 303 | `import <파일명>`의 형태로 같은 디렉토리에 있는 `파일명.planet`을 가져올 수 있다. 304 | 305 | `test.planet` 306 | ``` 307 | def print_test(){ 308 | print("test") 309 | } 310 | ``` 311 | 312 | `main.planet` 313 | ``` 314 | import test 315 | test.print_test() 316 | ``` 317 | 318 | `main.planet`을 컴파일 했을 때 319 | ``` 320 | test 321 | ``` 322 | 323 | ## execute 324 | 1. `if function`을 제외하고는 거의 대부분 마크 문법 그대로 사용해도 된다. 325 | ### if function 326 | - 함수를 정의했다면 `execute(if function __namespace__:test)`의 형태로 사용 가능하다 327 | - 함수를 정의하지 않고 아래와 같은 형태로도 사용 가능하다 328 | ``` 329 | execute(if function { 330 | return 1 331 | } positioned 0 0 0){ 332 | print("성공!") 333 | } 334 | ``` 335 | 336 | 337 | ## 내장 함수 338 | ### 함수명(자료형 인자, ...) 339 | `함수명`에 관한 설명 340 | `자료형`이 `any`로 적혀있는 경우, 어떤 자료형이든 상관 없다는 얘기이다. 341 | `...`이 있는 경우엔 인자가 몇개든 들어갈 수 있다는 것이다 342 | ### print(any a1, any a2, ...) 343 | `a1 a2 ...`의 형태로 채팅창에 출력된다 344 | ``` 345 | var a = 123 346 | print(a) 347 | ``` 348 | 349 | ``` 350 | 123 351 | ``` 352 | ### random() 353 | 0~1 사이의 랜덤한 실수를 반환한다 354 | ``` 355 | random() 356 | ``` 357 | ### type(any a) 358 | `a`의 자료형을 문자열로 반환한다 359 | ``` 360 | var test = 1.0 361 | print(type(test)) 362 | ``` 363 | 364 | ``` 365 | float 366 | ``` 367 | ### round(float|double a) 368 | `float` 또는 `double` 자료형을 반올림하여 `int`로 반환한다 369 | ``` 370 | print(round(1.2)) 371 | ``` 372 | 373 | ``` 374 | 1 375 | ``` 376 | ### get_score(string player, string objective) 377 | `player`의 `objective` 점수를 가져온다 378 | `/scoreboard players get {player} {objective}`와 같은 역할이다 379 | ``` 380 | /scoreboard objectives add test dummy 381 | /scoreboard players set asdf test 100 382 | print(get_score("asdf", "test")) 383 | ``` 384 | 385 | ``` 386 | 100 387 | ``` 388 | ### set_score(string player, string objective, any var) 389 | `player`의 `objective`에 `var`의 값을 스코어로 넣는다 390 | `/scoreboard players set {player} {objective} {var}`와 같은 역할이다 391 | `var`를 반환한다 392 | ``` 393 | var a = 10 394 | print(set_score("test", "num", a)) 395 | /tellraw @a {"score":{"name":"test","objective":"num"}} 396 | ``` 397 | 398 | ``` 399 | 10 400 | 10 401 | ``` 402 | ### get_data(string from, string|entity name, string dir) 403 | - `from`은 `entity`, `block`, `storage` 중 한가지여야 한다. 404 | - `name`은 블록의 좌표, 저장소의 이름, 엔티티 중 한가지여야 한다 405 | - `dir`은 가져오고자 하는 nbt의 경로를 뜻한다 406 | `/data get {from} {name} {dir}`와 같은 역할이다 407 | ``` 408 | /data modify storage minecraft:test test_dir set value "it's test string!" 409 | print(get_data("storage", "minecraft:test", "test_dir")) 410 | ``` 411 | 412 | ``` 413 | it's test string! 414 | ``` 415 | ### set_data(string from, string|entity name, string dir, any var) 416 | - `from`은 `entity`, `block`, `storage` 중 한가지여야 한다. 417 | - `name`은 블록의 좌표, 저장소의 이름, 엔티티 중 한가지여야 한다 418 | - `dir`은 설정하고자 하는 nbt의 경로를 뜻한다 419 | `/data modify {from} {name} {dir} set value {var}`와 같은 역할이다 420 | ``` 421 | set_data("storage", "minecraft:test", "test_dir", "it's test string!") 422 | print(get_data("storage", "minecraft:test", "test_dir")) 423 | ``` 424 | ### append(any[] arr, any element) 425 | - `arr`은 원소를 추가할 배열이다. 426 | - `element`는 추가할 원소이다 427 | ` `/data modify storage 40planet:values {arr} append value {element}`와 같은 역할이다 428 | ``` 429 | var arr = [] 430 | append(arr, 1) 431 | var test = 2 432 | append(arr, test) 433 | print(arr) 434 | ``` 435 | ### del(any var) 436 | - 저장소에서 `var`을 지웁니다 437 | - 예) `del(arr[1])` 438 | - `/data remove storage 40planet:values {var}`와 같은 역할이다 439 | ### len(any var) 440 | - 배열 또는 string 타입만 받습니다 441 | - `var`의 길이를 반환합니다 442 | ### is_module() 443 | - 해당 파일이 모듈로써 불러와진 것인지 판단해준다 444 | - 파이썬의 `__name__ == "__main__"` 조건문 역할을 해준다. 445 | ``` 446 | if(is_module()){ 447 | print("this is not main") 448 | } 449 | ``` 450 | ### divide(int|float|double var, int|float|double var2) 451 | - `var / var2`를 소수점 아래 5자리까지 계산해준다 452 | - 반환값의 타입은 `float`이다 453 | ``` 454 | print(divide(1, 2)) 455 | ``` 456 | ### multiply(int|float|double var, int|float|double var2) 457 | - `var * var2`를 소수점 아래 5자리까지 계산해준다 458 | - 반환값의 타입은 `float`이다 459 | ``` 460 | print(multiply(2, 3)) 461 | ``` 462 | ### int(any a) 463 | `a`를 `int` 자료형으로 변환해준다 464 | `float` 또는 `double`의 경우엔 `round(a)`와 같다 465 | ``` 466 | print(int(1.2)) 467 | print(int("3")) 468 | ``` 469 | 470 | ``` 471 | 1 472 | 3 473 | ``` 474 | ### float(any a) 475 | `a`를 `float`로 변환해준다 476 | ``` 477 | print(float(1)) 478 | ``` 479 | 480 | ``` 481 | 1.0f 482 | ``` 483 | ### double(any a) 484 | `a`를 `double`로 변환해준다 485 | ``` 486 | print(double(1)) 487 | ``` 488 | 489 | ``` 490 | 1.0d 491 | ``` 492 | ### bool(any a) 493 | `a`를 `bool`로 변환해준다 494 | ``` 495 | print(bool(100)) 496 | ``` 497 | 498 | ``` 499 | 1 500 | ``` 501 | ### string(any a) 502 | `a`를 `string`으로 변환해준다 503 | ``` 504 | print(string(1 + 1)) 505 | ``` 506 | 507 | ``` 508 | 2 509 | ``` 510 | -------------------------------------------------------------------------------- /README_en.md: -------------------------------------------------------------------------------- 1 | # Datapack-Compiler 2 | The aim of this project is to create Minecraft Datapack compiler.\ 3 | It was created by 40planet, and free use is permitted as long as the link is indicated. 4 | 5 | 6 | - [How to Use](#how-to-use) 7 | - [Vscode Highlighter Extension](#vscode-highlighter-extension) 8 | - [Contribute](#contribute) 9 | - [Syntax](#syntax) 10 | - [General](#general) 11 | - [execute](#execute) 12 | - [import](#import) 13 | - [Built-In Function](#built-in-function) 14 | 15 | # How to Use 16 | There is a video tutorial! Check out [Comet Tutorial](https://youtu.be/vzlmWR5MqCY). 17 | 18 | ## Install and Run 19 | ### Use Compiled Version (Windows Only) 20 | 1. Download `compiler.exe` on the [release tab](https://github.com/alexmonkey05/Datapack-Compiler/releases) 21 | 1. There are two ways to run. Running `compiler.exe` is entering into GUI mode, and running `compiler.exe --cli ` is entering into CLI mode. 22 | 23 | #### Arguments (CLI mode) 24 | | Argument | Description | 25 | | ---- | ---- | 26 | | `--cli` | Use cli instead of gui | 27 | | `-p ` or `--planet` | Select file to compile | 28 | | `-v ` or `--version` | Select minecraft version | 29 | | `-d ` or `--dist` | Select folder to locate output | 30 | | `-n ` or `--name` | Input namespace (default=`pack`) | 31 | | `-h` or `--help` | Show help page | 32 | 33 | #### Demo (CLI mode) 34 | ``` 35 | compiler.exe --cli --planet ./a.planet --version 1.21 --dist ./world/datapacks --name packpack 36 | ``` 37 | ``` 38 | compiler.exe --cli -p ./a.planet -v 1.21 -d ./world/datapacks -n packpack 39 | ``` 40 | 41 | ### Use Project Code (Windows, macOS, Linux) 42 | 1. Download project codes on the [release tab](https://github.com/alexmonkey05/Datapack-Compiler/releases) 43 | 1. Run `cd /path/to/project` 44 | 1. Run `pip install -r requirements.txt`. It will install the required package automatically.\ 45 | **[Warning]** If you are not Windows user, you may need to install `sudo apt-get install python3-tk` 46 | 1. Run `python new_compiler.py`(Windows) or `python3 new_compiler.py`(Universal). It will enter into GUI mode. 47 | 48 | ## GUI mode 49 | | 50 | :----: | :----: 51 | When success | When failed 52 | 53 | - The field of namespace is lowercase-only. The default value is `pack` 54 | - You can compile your code using `compile` button 55 | - Put generated datapack and `basic_1.20.zip` or `basic_1.21.zip` in the minecraft save's `datapacks` folder. 56 | - Now refresh the datapack by executing `/reload` in the minecraft session. 57 | 58 | # Vscode Highlighter Extension 59 | [Comet Highlighter(VSC Marketplace Link)](https://marketplace.visualstudio.com/items?itemName=alexmonkey05.comet-highlighter) 60 | You can use the link above or run VSCode and search for Comet Highlighter in extensions to download and use it. 61 | This extension only displays colors and does not have an auto-completion feature. 62 | 63 | # Contribute 64 | - You can generate executable by entering this command. 65 | ``` 66 | pyinstaller --noconfirm --onefile --console --add-data "\grammer.lark;." --add-data "\web;web/" "\new_compiler.py" 67 | ``` 68 | 69 | # Syntax 70 | ## General 71 | ### Data types 72 | - int 73 | - intager like `1`, `-2`, `100` 74 | - float, double 75 | - decimal like `1.0`, `3.14` 76 | - string 77 | - string like `"This is string"` 78 | - entity 79 | - selector like `@a[tag=player]` 80 | - nbt 81 | - json like `{id:"minecraft:block_display",Tags:["temp"]}` 82 | ### Define variable 83 | Declared in the form `var ` 84 | ``` 85 | var a 86 | var b = 2.0 87 | var c = @p[tag=player] 88 | var d = @p[tag=^b&] # ^b& is macro 89 | ``` 90 | 91 | Array declarations are declared just like other variables. 92 | ``` 93 | var array = [1, 2, 3] 94 | ``` 95 | ### Local variable 96 | ``` 97 | var a 98 | if ( condition ) { 99 | var a 100 | } 101 | ``` 102 | At this time, a inside the if statement and a outside the if statement are different variables. 103 | Also, since a is declared inside the if statement, a outside of it cannot be accessed. 104 | ### Line break 105 | Consider `\n` or `;` as the end of a command 106 | - However, there are some exceptions such as `[`, `{`, etc. 107 | ``` 108 | var a 109 | var b = { 110 | test: "asdf" 111 | } 112 | ``` 113 | 114 | ``` 115 | var a; 116 | var b = { 117 | test: "asdf" 118 | }; 119 | ``` 120 | ### Operations 121 | Operations are performed in the following order: 122 | parenthesis > member > arithmetic > relationship > logic (and, or) > assignment. 123 | - parenthesis 124 | - `()` 125 | - member(Operations to access elements of an array) 126 | - `[]` 127 | - arithmetic 128 | - `+` 129 | - `-` 130 | - `*` 131 | - `/` 132 | - `%` 133 | - In the case of `double` and `float`, the value is preserved only up to 2 digits after the decimal point. If you want to get more accurate values, it is better to use the `divide` and `multiply` functions. 134 | - relationship 135 | - `==` 136 | - `!=` 137 | - `<=` 138 | - `>=` 139 | - `<` 140 | - `>` 141 | - logic 142 | - `and` 143 | - `or` 144 | - `!` 145 | - assignment 146 | - `=` 147 | If the data types of the operands of an operation are different, an error occurs. 148 | However, in the case of `double`, `int` and `float`, no error occurs. 149 | ``` 150 | 1 + "1" 151 | ``` 152 | 153 | ``` 154 | Runtime Error: Operand must have same type 155 | ``` 156 | The result of an operation follows the last operand. 157 | ex) 0.3 * 1 = 0 158 | In the case of `!`, you must put parentheses after it, such as `!(is_module())`. 159 | In other words, it should be used like a function. 160 | ### if / else 161 | Write in the format `if( ){ ~~~ }` 162 | If the curly braces are omitted, only one command line following the condition is executed. 163 | ``` 164 | var a = 0; 165 | if(a == 0){ 166 | a = a + 1; 167 | } 168 | ``` 169 | 170 | ``` 171 | var a = 0 172 | if(a == 0) 173 | a = a + 1 174 | ``` 175 | You can use else in the form `if (...) {...} else {...}`. 176 | Likewise, if you omit the curly braces, only one line of commands is executed. 177 | ``` 178 | var a = 0 179 | if(a == 1){ 180 | a = a + 1 181 | } else { 182 | a = a - 1 183 | } 184 | ``` 185 | 186 | ``` 187 | var a = 0 188 | if(a == 1){ 189 | a = a + 1 190 | } else 191 | a = a - 1 192 | ``` 193 | The `else if` statement is also supported because if the curly braces are omitted, only the next single line of command is executed. 194 | However, bugs may occur when using else if, so it is recommended to use curly braces whenever possible. 195 | ``` 196 | var a = 0 197 | if(a == 1){ 198 | a = a + 1 199 | } else if (a == 0){ 200 | a = a + 2 201 | } 202 | ``` 203 | You can just put a variable in the condition without an operation. 204 | ``` 205 | var a = 1 206 | if(a){ # true 207 | print(a) 208 | } 209 | ``` 210 | At this time, the standard for judging true/false follows Minecraft's `execute store` syntax. 211 | Because of this, if the following values ​​are entered, false may be returned. 212 | - "" (empty string) 213 | - 0.4 (decimal number that becomes 0 when rounded) 214 | - -1 (negative number) 215 | - [] (empty array) 216 | ### while 217 | In the case of `while`, it can be written in the same form as `if`. 218 | ``` 219 | var a = 0 220 | while(a < 10){ 221 | a = a + 1 222 | } 223 | ``` 224 | 225 | ``` 226 | var a = 0 227 | while(a < 10) 228 | a = a + 1 229 | ``` 230 | You can stop the loop using the `break` keyword. 231 | `continue` and `for` are not supported 232 | 233 | ### Define function 234 | You can declare a function by writing it in the form `def ( [parameter] ){...}`. 235 | `[parameter]` can be omitted if necessary. 236 | ``` 237 | def tick(){ 238 | var a = 1 239 | } 240 | ``` 241 | 242 | ``` 243 | def test(var a, var b){ 244 | print(a, b) 245 | } 246 | ``` 247 | If you use capital letters in a function name, Minecraft will assume that the function does not exist. 248 | ~~Idiot~~ 249 | So let’s avoid using capital letters in function names. 250 | 251 | - If you declare a function named tick through `def tick`, this function is executed as a tick. 252 | - If you declare a function named load through `def load`, this function is executed once when the map is loaded. 253 | - `load` and `tick` executed like this cannot accept arguments. 254 | ### Call function 255 | You can call a function by writing it as `function name (argument)`. 256 | ``` 257 | def wa(var a){ 258 | return "sans" 259 | } 260 | 261 | def load(){ 262 | wa(3) 263 | } 264 | ``` 265 | If you want to call a function using the `/function` command, you can write it as follows: 266 | At this time, the most recently used argument is used once again. 267 | ``` 268 | def dumb_function(var a){ 269 | return a 270 | } 271 | 272 | /function __namespace__:dumb_function 273 | ``` 274 | `__namespace__` will be replaced with the namespace entered by the user. 275 | If it was `imported` as a module, `__namespace__` will be changed to the format `namespace:filename/`, so there is no need to worry. 276 | ### Minecraft command 277 | If you put `/` at the beginning, it will be recognized as a Minecraft command. 278 | ``` 279 | /say a 280 | /gamemode creative @a 281 | ``` 282 | 283 | You can use like macro when you wrote like `^variable&` 284 | ``` 285 | var a = 123 286 | /say ^a& 287 | ``` 288 | 289 | ``` 290 | [@] 123 291 | ``` 292 | 293 | ### Comment 294 | You can comment using `#` or `/#` 295 | ``` 296 | # Comments not written in the data pack 297 | /# Comments written in data pack 298 | ``` 299 | ~~Actually, I was wondering if `/#` was necessary, but I wrote it down first~~ 300 | 301 | ## import 302 | You can import `filename.planet` in the same directory in the form of `import `. 303 | `test.planet` 304 | ``` 305 | def print_test(){ 306 | print("test") 307 | } 308 | ``` 309 | 310 | `main.planet` 311 | ``` 312 | import test 313 | test.print_test() 314 | ``` 315 | 316 | When compile `main.planet` 317 | ``` 318 | test 319 | ``` 320 | 321 | ## execute 322 | - Except for `if function`, you can almost always use the mark syntax as is. 323 | ### if function 324 | - If you have defined a function, it can be used in the form of `execute(if function __namespace__:test)` 325 | - It can also be used in the form below without defining a function 326 | ``` 327 | execute(if function { 328 | return 1 329 | } positioned 0 0 0){ 330 | print("success!") 331 | } 332 | ``` 333 | 334 | 335 | ## Built-in function 336 | ### Function(type arguments, ...) 337 | Description of `function` 338 | If `type` is written as `any`, it means that any data type does not matter. 339 | If there is `...`, any number of arguments can be entered. 340 | ### print(any a1, any a2, ...) 341 | It is displayed in the chat window in the form of `a1 a2 ...` 342 | ``` 343 | var a = 123 344 | print(a) 345 | ``` 346 | 347 | ``` 348 | 123 349 | ``` 350 | ### random() 351 | Returns a random double between 0 and 1. 352 | ``` 353 | random() 354 | ``` 355 | ### type(any a) 356 | Returns the type of `a` as a string. 357 | ``` 358 | var test = 1.0 359 | print(type(test)) 360 | ``` 361 | 362 | ``` 363 | float 364 | ``` 365 | ### round(float|double a) 366 | Rounds the data type `float` or `double` and returns it as `int`. 367 | ``` 368 | print(round(1.2)) 369 | ``` 370 | 371 | ``` 372 | 1 373 | ``` 374 | ### get_score(string player, string objective) 375 | Gets the `objective` score of `player` 376 | Same as `/scoreboard players get {player} {objective}` 377 | ``` 378 | /scoreboard objectives add test dummy 379 | /scoreboard players set asdf test 100 380 | print(get_score("asdf", "test")) 381 | ``` 382 | 383 | ``` 384 | 100 385 | ``` 386 | ### set_score(string player, string objective, any var) 387 | Inserts the value of `var` into the `objective` of `player` as the score. 388 | Same role as `/scoreboard players set {player} {objective} {var}` 389 | returns `var` 390 | ``` 391 | var a = 10 392 | print(set_score("test", "num", a)) 393 | /tellraw @a {"score":{"name":"test","objective":"num"}} 394 | ``` 395 | 396 | ``` 397 | 10 398 | 10 399 | ``` 400 | ### get_data(string from, string|entity name, string dir) 401 | - `from` must be one of `entity`, `block`, or `storage`. 402 | - `name` must be one of block coordinates, storage name, or entity. 403 | - `dir` refers to the path of the nbt you want to import. 404 | Same as `/data get {from} {name} {dir}`. 405 | ``` 406 | /data modify storage minecraft:test test_dir set value "it's test string!" 407 | print(get_data("storage", "minecraft:test", "test_dir")) 408 | ``` 409 | 410 | ``` 411 | it's test string! 412 | ``` 413 | ### set_data(string from, string|entity name, string dir, any var) 414 | - `from` must be one of `entity`, `block`, or `storage`. 415 | - `name` must be one of block coordinates, storage name, or entity. 416 | - `dir` refers to the path of the nbt you want to set. 417 | Same as `/data get {from} {name} {dir}`. 418 | ``` 419 | set_data("storage", "minecraft:test", "test_dir", "it's test string!") 420 | print(get_data("storage", "minecraft:test", "test_dir")) 421 | ``` 422 | ### append(any[] arr, any element) 423 | - `arr` is the array to add elements to. 424 | - `element` is the element to be added 425 | - Same as `/data modify storage 40planet:values ​​{arr} append value {element}` 426 | ``` 427 | var arr = [] 428 | append(arr, 1) 429 | var test = 2 430 | append(arr, test) 431 | print(arr) 432 | ``` 433 | ### del(any var) 434 | - Delete `var` from the repository 435 | - example) `del(arr[1])` 436 | - Same as `/data remove storage 40planet:values ​​{var}` 437 | ### len(any var) 438 | - Only accepts array or string types 439 | - Returns the length of `var` 440 | ### is_module() 441 | - Determines whether the file has been loaded as a module 442 | - Functions as Python's `__name__ == "__main__"` conditional statement. 443 | ``` 444 | if(is_module()){ 445 | print("this is not main") 446 | } 447 | ``` 448 | ### divide(int|float|double var, int|float|double var2) 449 | - Calculates `var / var2` to 5 decimal places. 450 | - Return value's type is `float` 451 | ``` 452 | print(divide(1, 2)) 453 | ``` 454 | ### multiply(int|float|double var, int|float|double var2) 455 | - Calculates `var * var2` to 5 decimal places. 456 | - Return value's type is `float` 457 | ``` 458 | print(multiply(2, 3)) 459 | ``` 460 | ### int(any a) 461 | Converts `a` to `int` 자료형으 462 | `float` 또는 `double`의 경우엔 `round(a)`와 같다 463 | ``` 464 | print(int(1.2)) 465 | print(int("3")) 466 | ``` 467 | 468 | ``` 469 | 1 470 | 3 471 | ``` 472 | ### float(any a) 473 | Converts `a` to `float` 474 | ``` 475 | print(float(1)) 476 | ``` 477 | 478 | ``` 479 | 1.0f 480 | ``` 481 | ### double(any a) 482 | Converts `a` to `double` 483 | ``` 484 | print(double(1)) 485 | ``` 486 | 487 | ``` 488 | 1.0d 489 | ``` 490 | ### bool(any a) 491 | Converts `a` to `bool` 492 | ``` 493 | print(bool(100)) 494 | ``` 495 | 496 | ``` 497 | 1 498 | ``` 499 | ### string(any a) 500 | Converts `a` to `string`으 501 | ``` 502 | print(string(1 + 1)) 503 | ``` 504 | 505 | ``` 506 | 2 507 | ``` 508 | ### entity(string a) 509 | Converts `a` to `entity` 510 | **It is still incomplete, so it is recommended to only use variables like `"@a"`** 511 | ``` 512 | var test = "@s" 513 | var self = entity(test) 514 | def print_self(){ 515 | print(self) 516 | } 517 | ``` 518 | 519 | ``` 520 | 521 | ``` 522 | -------------------------------------------------------------------------------- /__pycache__/consts.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexmonkey05/Datapack-Compiler/51315f321c09dc301008e8fc4df4297ab89b2cf0/__pycache__/consts.cpython-312.pyc -------------------------------------------------------------------------------- /__pycache__/logger.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexmonkey05/Datapack-Compiler/51315f321c09dc301008e8fc4df4297ab89b2cf0/__pycache__/logger.cpython-312.pyc -------------------------------------------------------------------------------- /basic_1.20.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexmonkey05/Datapack-Compiler/51315f321c09dc301008e8fc4df4297ab89b2cf0/basic_1.20.zip -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/array/add.mcfunction: -------------------------------------------------------------------------------- 1 | execute unless data storage 40planet:value var2[0] run return run data modify storage 40planet:value var1 append from storage 40planet:value var2 2 | 3 | execute store result score #len 40planet_num run data get storage 40planet:value var2 4 | scoreboard players set #idx 40planet_num -1 5 | function basic:array/add/repeat 6 | return run data get storage 40planet:value var1 -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/array/add/macro.mcfunction: -------------------------------------------------------------------------------- 1 | $data modify storage 40planet:value var1 append from storage 40planet:value var2[$(idx)] -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/array/add/repeat.mcfunction: -------------------------------------------------------------------------------- 1 | execute store result storage 40planet:value idx int 1 run scoreboard players add #idx 40planet_num 1 2 | 3 | function basic:array/add/macro with storage 40planet:value 4 | 5 | execute if score #idx 40planet_num < #len 40planet_num run function basic:array/add/repeat -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/array/execute.mcfunction: -------------------------------------------------------------------------------- 1 | execute if score #operator_type 40planet_num matches 2..11 run tellraw @a {"text": "Runtime Error : Array only can operate \"add\"","color": "red"} 2 | execute if score #operator_type 40planet_num matches 2..11 run return fail 3 | 4 | execute if score #operator_type 40planet_num matches 1 run return run function basic:array/add 5 | 6 | execute if score #operator_type 40planet_num matches 12 store result score #temp 40planet_num run data get storage 40planet:value var1 7 | execute if score #operator_type 40planet_num matches 12 run return run execute unless score #temp 40planet_num matches 0 8 | 9 | execute if score #operator_type 40planet_num matches 13 run return run function basic:array/member/execute -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/array/member/execute.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | 3 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.int_arr append from storage 40planet:value var2 4 | 5 | execute unless score #type 40planet_num matches 1 run tellraw @a {"text": "Runtime Error : Index must be int type","color": "red"} 6 | execute unless score #type 40planet_num matches 1 run return fail 7 | 8 | return run function basic:array/member/macro with storage 40planet:value -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/array/member/macro.mcfunction: -------------------------------------------------------------------------------- 1 | $return run data modify storage 40planet:value var1 set from storage 40planet:value var1[$(var2)] -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/byte/execute.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute unless score #var1_type 40planet_num matches 5 run tellraw @a {"text": "Runtime Error : Operands must be of the same data type","color": "red"} 3 | execute unless score #var1_type 40planet_num matches 5 run return fail 4 | 5 | execute store result score #var1 40planet_num run data get storage 40planet:value var1 6 | execute store result score #var2 40planet_num run data get storage 40planet:value var2 7 | 8 | execute if score #operator_type 40planet_num matches 1 run return run scoreboard players operation #var1 40planet_num += #var2 40planet_num 9 | execute if score #operator_type 40planet_num matches 2 run return run scoreboard players operation #var1 40planet_num -= #var2 40planet_num 10 | execute if score #operator_type 40planet_num matches 3 run return run scoreboard players operation #var1 40planet_num *= #var2 40planet_num 11 | execute if score #operator_type 40planet_num matches 4 run return run scoreboard players operation #var1 40planet_num /= #var2 40planet_num 12 | execute if score #operator_type 40planet_num matches 5 run return run scoreboard players operation #var1 40planet_num %= #var2 40planet_num 13 | execute if score #operator_type 40planet_num matches 6 run return run execute if score #var1 40planet_num = #var2 40planet_num 14 | execute if score #operator_type 40planet_num matches 7 run return run execute unless score #var1 40planet_num = #var2 40planet_num 15 | execute if score #operator_type 40planet_num matches 8 run return run execute if score #var1 40planet_num >= #var2 40planet_num 16 | execute if score #operator_type 40planet_num matches 9 run return run execute if score #var1 40planet_num > #var2 40planet_num 17 | execute if score #operator_type 40planet_num matches 10 run return run execute if score #var1 40planet_num <= #var2 40planet_num 18 | execute if score #operator_type 40planet_num matches 11 run return run execute if score #var1 40planet_num < #var2 40planet_num -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/double/convert/4.mcfunction: -------------------------------------------------------------------------------- 1 | $data modify storage 40planet:value var1 set value $(type_var)d -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/double/convert/execute.mcfunction: -------------------------------------------------------------------------------- 1 | execute if score #type 40planet_num matches 4 run return run function basic:double/convert/4 with storage 40planet:value 2 | execute store result storage 40planet:value var1 double 0.01 run data get storage 40planet:value type_var 100 -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/double/execute.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute unless score #var1_type 40planet_num matches 1..3 run tellraw @a {"text": "Runtime Error : Operands must be of the same data type","color": "red"} 3 | execute unless score #var1_type 40planet_num matches 1..3 run return fail 4 | 5 | execute store result score #var1 40planet_num run data get storage 40planet:value var1 100 6 | execute store result score #var2 40planet_num run data get storage 40planet:value var2 100 7 | 8 | execute if score #operator_type 40planet_num matches 1 run return run scoreboard players operation #var1 40planet_num += #var2 40planet_num 9 | execute if score #operator_type 40planet_num matches 2 run return run scoreboard players operation #var1 40planet_num -= #var2 40planet_num 10 | execute if score #operator_type 40planet_num matches 3 run scoreboard players operation #var1 40planet_num *= #var2 40planet_num 11 | execute if score #operator_type 40planet_num matches 3 run return run scoreboard players operation #var1 40planet_num /= 100 40planet_num 12 | execute if score #operator_type 40planet_num matches 4 run scoreboard players operation #var1 40planet_num *= 100 40planet_num 13 | execute if score #operator_type 40planet_num matches 4 run return run scoreboard players operation #var1 40planet_num /= #var2 40planet_num 14 | execute if score #operator_type 40planet_num matches 5 run return run scoreboard players operation #var1 40planet_num %= #var2 40planet_num 15 | execute if score #operator_type 40planet_num matches 6 run return run execute if score #var1 40planet_num = #var2 40planet_num 16 | execute if score #operator_type 40planet_num matches 7 run return run execute unless score #var1 40planet_num = #var2 40planet_num 17 | execute if score #operator_type 40planet_num matches 8 run return run execute if score #var1 40planet_num >= #var2 40planet_num 18 | execute if score #operator_type 40planet_num matches 9 run return run execute if score #var1 40planet_num > #var2 40planet_num 19 | execute if score #operator_type 40planet_num matches 10 run return run execute if score #var1 40planet_num <= #var2 40planet_num 20 | execute if score #operator_type 40planet_num matches 11 run return run execute if score #var1 40planet_num < #var2 40planet_num -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/float/convert/4.mcfunction: -------------------------------------------------------------------------------- 1 | $data modify storage 40planet:value var1 set value $(type_var)f -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/float/convert/execute.mcfunction: -------------------------------------------------------------------------------- 1 | execute if score #type 40planet_num matches 4 run return run function basic:float/convert/4 with storage 40planet:value 2 | execute store result storage 40planet:value var1 float 0.01 run data get storage 40planet:value type_var 100 -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/float/execute.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute unless score #var1_type 40planet_num matches 1..3 run tellraw @a {"text": "Runtime Error : Operands must be of the same data type","color": "red"} 3 | execute unless score #var1_type 40planet_num matches 1..3 run return fail 4 | 5 | execute store result score #var1 40planet_num run data get storage 40planet:value var1 100 6 | execute store result score #var2 40planet_num run data get storage 40planet:value var2 100 7 | 8 | execute if score #operator_type 40planet_num matches 1 run return run scoreboard players operation #var1 40planet_num += #var2 40planet_num 9 | execute if score #operator_type 40planet_num matches 2 run return run scoreboard players operation #var1 40planet_num -= #var2 40planet_num 10 | execute if score #operator_type 40planet_num matches 3 run scoreboard players operation #var1 40planet_num *= #var2 40planet_num 11 | execute if score #operator_type 40planet_num matches 3 run return run scoreboard players operation #var1 40planet_num /= 100 40planet_num 12 | execute if score #operator_type 40planet_num matches 4 run scoreboard players operation #var1 40planet_num *= 100 40planet_num 13 | execute if score #operator_type 40planet_num matches 4 run return run scoreboard players operation #var1 40planet_num /= #var2 40planet_num 14 | execute if score #operator_type 40planet_num matches 5 run return run scoreboard players operation #var1 40planet_num %= #var2 40planet_num 15 | execute if score #operator_type 40planet_num matches 6 run return run execute if score #var1 40planet_num = #var2 40planet_num 16 | execute if score #operator_type 40planet_num matches 7 run return run execute unless score #var1 40planet_num = #var2 40planet_num 17 | execute if score #operator_type 40planet_num matches 8 run return run execute if score #var1 40planet_num >= #var2 40planet_num 18 | execute if score #operator_type 40planet_num matches 9 run return run execute if score #var1 40planet_num > #var2 40planet_num 19 | execute if score #operator_type 40planet_num matches 10 run return run execute if score #var1 40planet_num <= #var2 40planet_num 20 | execute if score #operator_type 40planet_num matches 11 run return run execute if score #var1 40planet_num < #var2 40planet_num -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/get_type_score.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.int_arr append from storage 40planet:value type_var 3 | execute if score #type 40planet_num matches 1 run data remove storage 40planet:value $type_arr.int_arr[1] 4 | execute if score #type 40planet_num matches 1 run return 1 5 | 6 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.float_arr append from storage 40planet:value type_var 7 | execute if score #type 40planet_num matches 1 run data remove storage 40planet:value $type_arr.float_arr[1] 8 | execute if score #type 40planet_num matches 1 run return 2 9 | 10 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.byte_arr append from storage 40planet:value type_var 11 | execute if score #type 40planet_num matches 1 run data remove storage 40planet:value $type_arr.byte_arr[1] 12 | execute if score #type 40planet_num matches 1 run return 5 13 | 14 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.double_arr append from storage 40planet:value type_var 15 | execute if score #type 40planet_num matches 1 run data remove storage 40planet:value $type_arr.double_arr[1] 16 | execute if score #type 40planet_num matches 1 run return 3 17 | 18 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.string_arr append from storage 40planet:value type_var 19 | execute if score #type 40planet_num matches 1 run data remove storage 40planet:value $type_arr.string_arr[1] 20 | execute if score #type 40planet_num matches 1 run return 4 21 | 22 | return 0 -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/int/convert.mcfunction: -------------------------------------------------------------------------------- 1 | execute store result storage 40planet:value type int 1 run function basic:get_type_score 2 | function basic:convert/execute with storage 40planet:value -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/int/convert/4.mcfunction: -------------------------------------------------------------------------------- 1 | $scoreboard players set #temp 40planet_num $(type_var) 2 | execute store result storage 40planet:value var1 int 1 run scoreboard players get #temp 40planet_num -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/int/convert/execute.mcfunction: -------------------------------------------------------------------------------- 1 | execute if score #type 40planet_num matches 4 run return run function basic:int/convert/4 with storage 40planet:value 2 | execute store result storage 40planet:value var1 int 1 run data get storage 40planet:value type_var -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/int/execute.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute unless score #var1_type 40planet_num matches 1..3 run tellraw @a {"text": "Runtime Error : Operands must be of the same data type","color": "red"} 3 | execute unless score #var1_type 40planet_num matches 1..3 run return fail 4 | 5 | execute store result score #var1 40planet_num run data get storage 40planet:value var1 6 | execute store result score #var2 40planet_num run data get storage 40planet:value var2 7 | 8 | execute if score #operator_type 40planet_num matches 1 run return run scoreboard players operation #var1 40planet_num += #var2 40planet_num 9 | execute if score #operator_type 40planet_num matches 2 run return run scoreboard players operation #var1 40planet_num -= #var2 40planet_num 10 | execute if score #operator_type 40planet_num matches 3 run return run scoreboard players operation #var1 40planet_num *= #var2 40planet_num 11 | execute if score #operator_type 40planet_num matches 4 run return run scoreboard players operation #var1 40planet_num /= #var2 40planet_num 12 | execute if score #operator_type 40planet_num matches 5 run return run scoreboard players operation #var1 40planet_num %= #var2 40planet_num 13 | execute if score #operator_type 40planet_num matches 6 run return run execute if score #var1 40planet_num = #var2 40planet_num 14 | execute if score #operator_type 40planet_num matches 7 run return run execute unless score #var1 40planet_num = #var2 40planet_num 15 | execute if score #operator_type 40planet_num matches 8 run return run execute if score #var1 40planet_num >= #var2 40planet_num 16 | execute if score #operator_type 40planet_num matches 9 run return run execute if score #var1 40planet_num > #var2 40planet_num 17 | execute if score #operator_type 40planet_num matches 10 run return run execute if score #var1 40planet_num <= #var2 40planet_num 18 | execute if score #operator_type 40planet_num matches 11 run return run execute if score #var1 40planet_num < #var2 40planet_num -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/load.mcfunction: -------------------------------------------------------------------------------- 1 | # This data pack was compiled with the 40planet's compiler. 2 | # https://github.com/alexmonkey05/Datapack-Interpreter 3 | scoreboard objectives add 40planet_num dummy 4 | scoreboard players set 100 40planet_num 100 5 | scoreboard players set #0 40planet_num 0 6 | kill 0-0-0-0-a 7 | summon text_display 0 0 0 {UUID:[I;0,0,0,10]} 8 | forceload add 0 0 9 | data remove storage 40planet:value $type_arr 10 | data modify storage 40planet:value $type_arr set value {int_arr:[1], float_arr:[1f], double_arr:[1d], string_arr:["1"], byte_arr:[1b]} 11 | data modify storage 40planet:value false set value 0b 12 | data modify storage 40planet:value true set value 1b 13 | say done! 14 | -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/operation.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute if data storage 40planet:value var1[0] run return run function basic:array/execute 3 | execute unless data storage 40planet:value var1[0] if data storage 40planet:value var2[0] run tellraw @a {"text": "Runtime Error : Array can only be operated with array","color": "red"} 4 | execute unless data storage 40planet:value var1[0] if data storage 40planet:value var2[0] run return fail 5 | 6 | data modify storage 40planet:value type_var set from storage 40planet:value var1 7 | execute store result score #var1_type 40planet_num run function basic:get_type_score 8 | 9 | # execute if score #var1_type 40planet_num matches 0 if score #operator_type 40planet_num matches 14 run return run function 10 | 11 | execute if score #var1_type 40planet_num matches 0 run tellraw @a {"text": "Runtime Error : nbt type can not be operated","color": "red"} 12 | execute if score #var1_type 40planet_num matches 0 run return fail 13 | 14 | execute if score #operator_type 40planet_num matches 12 store result score #var1 40planet_num run data get storage 40planet:value var1 15 | execute if score #operator_type 40planet_num matches 12 run return run execute unless score #var1 40planet_num matches 0 16 | 17 | data modify storage 40planet:value type_var set from storage 40planet:value var2 18 | execute store result score #var2_type 40planet_num run function basic:get_type_score 19 | execute if score #var2_type 40planet_num matches 0 run tellraw @a {"text": "Runtime Error : nbt type can not be operated","color": "red"} 20 | execute if score #var2_type 40planet_num matches 0 run return fail 21 | 22 | execute if score #var2_type 40planet_num matches 1 store result storage 40planet:value var1 int 1 run return run function basic:int/execute 23 | execute if score #var2_type 40planet_num matches 2 store result storage 40planet:value var1 float 0.01 run return run function basic:float/execute 24 | execute if score #var2_type 40planet_num matches 3 store result storage 40planet:value var1 double 0.01 run return run function basic:double/execute 25 | execute if score #var2_type 40planet_num matches 4 run return run function basic:string/execute 26 | execute if score #var2_type 40planet_num matches 5 store result storage 40planet:value var1 byte 1 run return run function basic:byte/execute 27 | 28 | # execute if score #var1_type 40planet_num matches 2..3 run return run data get storage 40planet:value var1 100 29 | # return run data get storage 40planet:value var1 -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/string/add.mcfunction: -------------------------------------------------------------------------------- 1 | $data modify storage 40planet:value return set value "$(var1)$(var2)" 2 | return run data get storage 40planet:value return -------------------------------------------------------------------------------- /basic_1.20/data/basic/functions/string/execute.mcfunction: -------------------------------------------------------------------------------- 1 | execute unless score #var1_type 40planet_num matches 4 run tellraw @a {"text": "Runtime Error : Operands must be of the same data type","color": "red"} 2 | execute unless score #var1_type 40planet_num matches 4 run return fail 3 | 4 | execute if score #operator_type 40planet_num matches 1 run return run function basic:string/add with storage 40planet:value 5 | execute if score #operator_type 40planet_num matches 2..5 run tellraw @a {"text": "Runtime Error : String only can operate \"add\"","color": "red"} 6 | execute if score #operator_type 40planet_num matches 2..5 run return fail 7 | execute if score #operator_type 40planet_num matches 6..7 store success score #var1 40planet_num run data modify storage 40planet:value var1 set from storage 40planet:value var2 8 | execute if score #operator_type 40planet_num matches 6 run return run execute if score #var1 40planet_num matches 0 9 | execute if score #operator_type 40planet_num matches 7 run return run execute if score #var1 40planet_num matches 1 10 | execute if score #operator_type 40planet_num matches 8..11 run tellraw @a {"text": "Runtime Error : String only can operate \"add\"","color": "red"} 11 | execute if score #operator_type 40planet_num matches 8..11 run return fail -------------------------------------------------------------------------------- /basic_1.20/data/minecraft/tags/functions/load.json: -------------------------------------------------------------------------------- 1 | {"values": ["basic:load"]} -------------------------------------------------------------------------------- /basic_1.20/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { "pack": {"pack_format": 9, "description": "by 40planet"} } -------------------------------------------------------------------------------- /basic_1.21.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexmonkey05/Datapack-Compiler/51315f321c09dc301008e8fc4df4297ab89b2cf0/basic_1.21.zip -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/array/add.mcfunction: -------------------------------------------------------------------------------- 1 | execute unless data storage 40planet:value var2[0] run return run data modify storage 40planet:value var1 append from storage 40planet:value var2 2 | 3 | execute store result score #len 40planet_num run data get storage 40planet:value var2 4 | scoreboard players set #idx 40planet_num -1 5 | function basic:array/add/repeat 6 | return run data get storage 40planet:value var1 -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/array/add/macro.mcfunction: -------------------------------------------------------------------------------- 1 | $data modify storage 40planet:value var1 append from storage 40planet:value var2[$(idx)] -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/array/add/repeat.mcfunction: -------------------------------------------------------------------------------- 1 | execute store result storage 40planet:value idx int 1 run scoreboard players add #idx 40planet_num 1 2 | 3 | function basic:array/add/macro with storage 40planet:value 4 | 5 | execute if score #idx 40planet_num < #len 40planet_num run function basic:array/add/repeat -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/array/execute.mcfunction: -------------------------------------------------------------------------------- 1 | execute if score #operator_type 40planet_num matches 2..11 run tellraw @a {"text": "Runtime Error : Array only can operate \"add\"","color": "red"} 2 | execute if score #operator_type 40planet_num matches 2..11 run return fail 3 | 4 | execute if score #operator_type 40planet_num matches 1 run return run function basic:array/add 5 | 6 | execute if score #operator_type 40planet_num matches 12 store result score #temp 40planet_num run data get storage 40planet:value var1 7 | execute if score #operator_type 40planet_num matches 12 run return run execute unless score #temp 40planet_num matches 0 8 | 9 | execute if score #operator_type 40planet_num matches 13 run return run function basic:array/member/execute -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/array/member/execute.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | 3 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.int_arr append from storage 40planet:value var2 4 | 5 | execute unless score #type 40planet_num matches 1 run tellraw @a {"text": "Runtime Error : Index must be int type","color": "red"} 6 | execute unless score #type 40planet_num matches 1 run return fail 7 | 8 | return run function basic:array/member/macro with storage 40planet:value -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/array/member/macro.mcfunction: -------------------------------------------------------------------------------- 1 | $return run data modify storage 40planet:value var1 set from storage 40planet:value var1[$(var2)] -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/byte/execute.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute unless score #var1_type 40planet_num matches 5 run tellraw @a {"text": "Runtime Error : Operands must be of the same data type","color": "red"} 3 | execute unless score #var1_type 40planet_num matches 5 run return fail 4 | 5 | execute store result score #var1 40planet_num run data get storage 40planet:value var1 6 | execute store result score #var2 40planet_num run data get storage 40planet:value var2 7 | 8 | execute if score #operator_type 40planet_num matches 1 run return run scoreboard players operation #var1 40planet_num += #var2 40planet_num 9 | execute if score #operator_type 40planet_num matches 2 run return run scoreboard players operation #var1 40planet_num -= #var2 40planet_num 10 | execute if score #operator_type 40planet_num matches 3 run return run scoreboard players operation #var1 40planet_num *= #var2 40planet_num 11 | execute if score #operator_type 40planet_num matches 4 run return run scoreboard players operation #var1 40planet_num /= #var2 40planet_num 12 | execute if score #operator_type 40planet_num matches 5 run return run scoreboard players operation #var1 40planet_num %= #var2 40planet_num 13 | execute if score #operator_type 40planet_num matches 6 run return run execute if score #var1 40planet_num = #var2 40planet_num 14 | execute if score #operator_type 40planet_num matches 7 run return run execute unless score #var1 40planet_num = #var2 40planet_num 15 | execute if score #operator_type 40planet_num matches 8 run return run execute if score #var1 40planet_num >= #var2 40planet_num 16 | execute if score #operator_type 40planet_num matches 9 run return run execute if score #var1 40planet_num > #var2 40planet_num 17 | execute if score #operator_type 40planet_num matches 10 run return run execute if score #var1 40planet_num <= #var2 40planet_num 18 | execute if score #operator_type 40planet_num matches 11 run return run execute if score #var1 40planet_num < #var2 40planet_num -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/double/convert/4.mcfunction: -------------------------------------------------------------------------------- 1 | $data modify storage 40planet:value var1 set value $(type_var)d -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/double/convert/execute.mcfunction: -------------------------------------------------------------------------------- 1 | execute if score #type 40planet_num matches 4 run return run function basic:float/convert/4 with storage 40planet:value 2 | execute store result storage 40planet:value var1 double 0.001 run data get storage 40planet:value type_var 1000 -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/double/execute.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute unless score #var1_type 40planet_num matches 1..3 run tellraw @a {"text": "Runtime Error : Operands must be of the same data type","color": "red"} 3 | execute unless score #var1_type 40planet_num matches 1..3 run return fail 4 | 5 | execute store result score #var1 40planet_num run data get storage 40planet:value var1 100 6 | execute store result score #var2 40planet_num run data get storage 40planet:value var2 100 7 | 8 | execute if score #operator_type 40planet_num matches 1 run return run scoreboard players operation #var1 40planet_num += #var2 40planet_num 9 | execute if score #operator_type 40planet_num matches 2 run return run scoreboard players operation #var1 40planet_num -= #var2 40planet_num 10 | execute if score #operator_type 40planet_num matches 3 run scoreboard players operation #var1 40planet_num *= #var2 40planet_num 11 | execute if score #operator_type 40planet_num matches 3 run return run scoreboard players operation #var1 40planet_num /= 100 40planet_num 12 | execute if score #operator_type 40planet_num matches 4 run scoreboard players operation #var1 40planet_num *= 100 40planet_num 13 | execute if score #operator_type 40planet_num matches 4 run return run scoreboard players operation #var1 40planet_num /= #var2 40planet_num 14 | execute if score #operator_type 40planet_num matches 5 run return run scoreboard players operation #var1 40planet_num %= #var2 40planet_num 15 | execute if score #operator_type 40planet_num matches 6 run return run execute if score #var1 40planet_num = #var2 40planet_num 16 | execute if score #operator_type 40planet_num matches 7 run return run execute unless score #var1 40planet_num = #var2 40planet_num 17 | execute if score #operator_type 40planet_num matches 8 run return run execute if score #var1 40planet_num >= #var2 40planet_num 18 | execute if score #operator_type 40planet_num matches 9 run return run execute if score #var1 40planet_num > #var2 40planet_num 19 | execute if score #operator_type 40planet_num matches 10 run return run execute if score #var1 40planet_num <= #var2 40planet_num 20 | execute if score #operator_type 40planet_num matches 11 run return run execute if score #var1 40planet_num < #var2 40planet_num -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/float/convert/4.mcfunction: -------------------------------------------------------------------------------- 1 | $data modify storage 40planet:value var1 set value $(type_var)f -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/float/convert/execute.mcfunction: -------------------------------------------------------------------------------- 1 | execute if score #type 40planet_num matches 4 run return run function basic:float/convert/4 with storage 40planet:value 2 | execute store result storage 40planet:value var1 float 0.01 run data get storage 40planet:value type_var 100 -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/float/execute.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute unless score #var1_type 40planet_num matches 1..3 run tellraw @a {"text": "Runtime Error : Operands must be of the same data type","color": "red"} 3 | execute unless score #var1_type 40planet_num matches 1..3 run return fail 4 | 5 | execute store result score #var1 40planet_num run data get storage 40planet:value var1 100 6 | execute store result score #var2 40planet_num run data get storage 40planet:value var2 100 7 | 8 | execute if score #operator_type 40planet_num matches 1 run return run scoreboard players operation #var1 40planet_num += #var2 40planet_num 9 | execute if score #operator_type 40planet_num matches 2 run return run scoreboard players operation #var1 40planet_num -= #var2 40planet_num 10 | execute if score #operator_type 40planet_num matches 3 run scoreboard players operation #var1 40planet_num *= #var2 40planet_num 11 | execute if score #operator_type 40planet_num matches 3 run return run scoreboard players operation #var1 40planet_num /= 100 40planet_num 12 | execute if score #operator_type 40planet_num matches 4 run scoreboard players operation #var1 40planet_num *= 100 40planet_num 13 | execute if score #operator_type 40planet_num matches 4 run return run scoreboard players operation #var1 40planet_num /= #var2 40planet_num 14 | execute if score #operator_type 40planet_num matches 5 run return run scoreboard players operation #var1 40planet_num %= #var2 40planet_num 15 | execute if score #operator_type 40planet_num matches 6 run return run execute if score #var1 40planet_num = #var2 40planet_num 16 | execute if score #operator_type 40planet_num matches 7 run return run execute unless score #var1 40planet_num = #var2 40planet_num 17 | execute if score #operator_type 40planet_num matches 8 run return run execute if score #var1 40planet_num >= #var2 40planet_num 18 | execute if score #operator_type 40planet_num matches 9 run return run execute if score #var1 40planet_num > #var2 40planet_num 19 | execute if score #operator_type 40planet_num matches 10 run return run execute if score #var1 40planet_num <= #var2 40planet_num 20 | execute if score #operator_type 40planet_num matches 11 run return run execute if score #var1 40planet_num < #var2 40planet_num -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/get_type_score.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.int_arr append from storage 40planet:value type_var 3 | execute if score #type 40planet_num matches 1 run data remove storage 40planet:value $type_arr.int_arr[1] 4 | execute if score #type 40planet_num matches 1 run return 1 5 | 6 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.float_arr append from storage 40planet:value type_var 7 | execute if score #type 40planet_num matches 1 run data remove storage 40planet:value $type_arr.float_arr[1] 8 | execute if score #type 40planet_num matches 1 run return 2 9 | 10 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.byte_arr append from storage 40planet:value type_var 11 | execute if score #type 40planet_num matches 1 run data remove storage 40planet:value $type_arr.byte_arr[1] 12 | execute if score #type 40planet_num matches 1 run return 5 13 | 14 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.double_arr append from storage 40planet:value type_var 15 | execute if score #type 40planet_num matches 1 run data remove storage 40planet:value $type_arr.double_arr[1] 16 | execute if score #type 40planet_num matches 1 run return 3 17 | 18 | execute store success score #type 40planet_num run data modify storage 40planet:value $type_arr.string_arr append from storage 40planet:value type_var 19 | execute if score #type 40planet_num matches 1 run data remove storage 40planet:value $type_arr.string_arr[1] 20 | execute if score #type 40planet_num matches 1 run return 4 21 | 22 | return 0 -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/int/convert.mcfunction: -------------------------------------------------------------------------------- 1 | execute store result storage 40planet:value type int 1 run function basic:get_type_score 2 | function basic:convert/execute with storage 40planet:value -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/int/convert/4.mcfunction: -------------------------------------------------------------------------------- 1 | $scoreboard players set #temp 40planet_num $(type_var) 2 | execute store result storage 40planet:value var1 int 1 run scoreboard players get #temp 40planet_num -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/int/convert/execute.mcfunction: -------------------------------------------------------------------------------- 1 | execute if score #type 40planet_num matches 4 run return run function basic:int/convert/4 with storage 40planet:value 2 | execute store result storage 40planet:value var1 int 1 run data get storage 40planet:value type_var -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/int/execute.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute unless score #var1_type 40planet_num matches 1..3 run tellraw @a {"text": "Runtime Error : Operands must be of the same data type","color": "red"} 3 | execute unless score #var1_type 40planet_num matches 1..3 run return fail 4 | 5 | execute store result score #var1 40planet_num run data get storage 40planet:value var1 6 | execute store result score #var2 40planet_num run data get storage 40planet:value var2 7 | 8 | execute if score #operator_type 40planet_num matches 1 run return run scoreboard players operation #var1 40planet_num += #var2 40planet_num 9 | execute if score #operator_type 40planet_num matches 2 run return run scoreboard players operation #var1 40planet_num -= #var2 40planet_num 10 | execute if score #operator_type 40planet_num matches 3 run return run scoreboard players operation #var1 40planet_num *= #var2 40planet_num 11 | execute if score #operator_type 40planet_num matches 4 run return run scoreboard players operation #var1 40planet_num /= #var2 40planet_num 12 | execute if score #operator_type 40planet_num matches 5 run return run scoreboard players operation #var1 40planet_num %= #var2 40planet_num 13 | execute if score #operator_type 40planet_num matches 6 run return run execute if score #var1 40planet_num = #var2 40planet_num 14 | execute if score #operator_type 40planet_num matches 7 run return run execute unless score #var1 40planet_num = #var2 40planet_num 15 | execute if score #operator_type 40planet_num matches 8 run return run execute if score #var1 40planet_num >= #var2 40planet_num 16 | execute if score #operator_type 40planet_num matches 9 run return run execute if score #var1 40planet_num > #var2 40planet_num 17 | execute if score #operator_type 40planet_num matches 10 run return run execute if score #var1 40planet_num <= #var2 40planet_num 18 | execute if score #operator_type 40planet_num matches 11 run return run execute if score #var1 40planet_num < #var2 40planet_num -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/load.mcfunction: -------------------------------------------------------------------------------- 1 | # This data pack was compiled with the 40planet's compiler. 2 | # https://github.com/alexmonkey05/Datapack-Interpreter 3 | scoreboard objectives add 40planet_num dummy 4 | scoreboard players set 100 40planet_num 100 5 | scoreboard players set #0 40planet_num 0 6 | kill 0-0-0-0-a 7 | summon text_display 0 0 0 {UUID:[I;0,0,0,10]} 8 | forceload add 0 0 9 | data remove storage 40planet:value $type_arr 10 | data modify storage 40planet:value $type_arr set value {int_arr:[1], float_arr:[1f], double_arr:[1d], string_arr:["1"], byte_arr:[1b]} 11 | data modify storage 40planet:value false set value 0b 12 | data modify storage 40planet:value true set value 1b 13 | say done! 14 | -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/operation.mcfunction: -------------------------------------------------------------------------------- 1 | 2 | execute if data storage 40planet:value var1[0] run return run function basic:array/execute 3 | execute unless data storage 40planet:value var1[0] if data storage 40planet:value var2[0] run tellraw @a {"text": "Runtime Error : Array can only be operated with array","color": "red"} 4 | execute unless data storage 40planet:value var1[0] if data storage 40planet:value var2[0] run return fail 5 | 6 | data modify storage 40planet:value type_var set from storage 40planet:value var1 7 | execute store result score #var1_type 40planet_num run function basic:get_type_score 8 | 9 | # execute if score #var1_type 40planet_num matches 0 if score #operator_type 40planet_num matches 14 run return run function 10 | 11 | execute if score #var1_type 40planet_num matches 0 run tellraw @a {"text": "Runtime Error : nbt type can not be operated","color": "red"} 12 | execute if score #var1_type 40planet_num matches 0 run return fail 13 | 14 | execute if score #operator_type 40planet_num matches 12 store result score #var1 40planet_num run data get storage 40planet:value var1 15 | execute if score #operator_type 40planet_num matches 12 run return run execute unless score #var1 40planet_num matches 0 16 | 17 | data modify storage 40planet:value type_var set from storage 40planet:value var2 18 | execute store result score #var2_type 40planet_num run function basic:get_type_score 19 | execute if score #var2_type 40planet_num matches 0 run tellraw @a {"text": "Runtime Error : nbt type can not be operated","color": "red"} 20 | execute if score #var2_type 40planet_num matches 0 run return fail 21 | 22 | execute if score #var2_type 40planet_num matches 1 store result storage 40planet:value var1 int 1 run return run function basic:int/execute 23 | execute if score #var2_type 40planet_num matches 2 store result storage 40planet:value var1 float 0.01 run return run function basic:float/execute 24 | execute if score #var2_type 40planet_num matches 3 store result storage 40planet:value var1 double 0.01 run return run function basic:double/execute 25 | execute if score #var2_type 40planet_num matches 4 run return run function basic:string/execute 26 | execute if score #var2_type 40planet_num matches 5 store result storage 40planet:value var1 byte 1 run return run function basic:byte/execute 27 | 28 | # execute if score #var1_type 40planet_num matches 2..3 run return run data get storage 40planet:value var1 100 29 | # return run data get storage 40planet:value var1 -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/string/add.mcfunction: -------------------------------------------------------------------------------- 1 | $data modify storage 40planet:value return set value "$(var1)$(var2)" 2 | return run data get storage 40planet:value return -------------------------------------------------------------------------------- /basic_1.21/data/basic/function/string/execute.mcfunction: -------------------------------------------------------------------------------- 1 | execute unless score #var1_type 40planet_num matches 4 run tellraw @a {"text": "Runtime Error : Operands must be of the same data type","color": "red"} 2 | execute unless score #var1_type 40planet_num matches 4 run return fail 3 | 4 | execute if score #operator_type 40planet_num matches 1 run return run function basic:string/add with storage 40planet:value 5 | execute if score #operator_type 40planet_num matches 2..5 run tellraw @a {"text": "Runtime Error : String only can operate \"add\"","color": "red"} 6 | execute if score #operator_type 40planet_num matches 2..5 run return fail 7 | execute if score #operator_type 40planet_num matches 6..7 store success score #var1 40planet_num run data modify storage 40planet:value var1 set from storage 40planet:value var2 8 | execute if score #operator_type 40planet_num matches 6 store result storage 40planet:value var1 int 1 run return run execute if score #var1 40planet_num matches 0 9 | execute if score #operator_type 40planet_num matches 7 store result storage 40planet:value var1 int 1 run return run execute if score #var1 40planet_num matches 1 10 | execute if score #operator_type 40planet_num matches 8..11 run tellraw @a {"text": "Runtime Error : String only can operate \"add\"","color": "red"} 11 | execute if score #operator_type 40planet_num matches 8..11 run return fail -------------------------------------------------------------------------------- /basic_1.21/data/minecraft/tags/function/load.json: -------------------------------------------------------------------------------- 1 | {"values": ["basic:load"]} -------------------------------------------------------------------------------- /basic_1.21/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { "pack": {"pack_format": 9, "description": "by 40planet"} } -------------------------------------------------------------------------------- /built_in_function.py: -------------------------------------------------------------------------------- 1 | from consts import SCORE_TYPES, MINECRAFT_TYPES, TYPES, SCOREBOARD_NAME, STORAGE_NAME, NAMESPACE, DIGITS, INTERPRETE_THESE, BUILT_IN_FUNCTION, OPERATION, OPERATOR_ID, CNAME, INT, ESCAPED_STRING, VariableComet, error_as_txt, Function, CometToken 2 | from transform import CometToken, CNAME, STORAGE_NAME, DatapackGenerater 3 | 4 | 5 | class BuiltInFunctions(DatapackGenerater): 6 | def __init__(self, datapack_generator): 7 | super().__init__(datapack_generator.version, datapack_generator.result_dir, datapack_generator.namespace, datapack_generator.filename, datapack_generator.is_module, datapack_generator.module_name, datapack_generator.visit_tokens) 8 | 9 | 10 | def fun_string(self, node, input_nodes): 11 | if 1 != len(input_nodes): 12 | raise ValueError(error_as_txt( 13 | node.children[0].token, 14 | "InvalidSyntaxError", 15 | self.filename, 16 | f"string must have only 1 parameters" 17 | )) 18 | input_node = input_nodes[0].children[0] 19 | var = input_node.name 20 | if var in INTERPRETE_THESE: 21 | var, error = self.interprete(input_node) 22 | if error: return None, error 23 | temp = self.get_temp() 24 | if var in self.variables: 25 | self.write(f"data modify storage {STORAGE_NAME} type_var set from storage {STORAGE_NAME} {self.variables[var][-1].temp}\n\ 26 | execute store result score #type {SCOREBOARD_NAME} run function basic:get_type_score\n\ 27 | execute if score #type {SCOREBOARD_NAME} matches 4 run data modify storage {STORAGE_NAME} {temp} set from storage {STORAGE_NAME} type_var\n\ 28 | execute unless score #type {SCOREBOARD_NAME} matches 4 run ") 29 | self.macro(f"$data modify storage {STORAGE_NAME} {temp} set value \"$({self.variables[var][-1].temp[5:]})\"\n") 30 | else: 31 | if var[0] == "\"": 32 | var = var[1:-1] 33 | self.write(f"data modify storage {STORAGE_NAME} {temp} set value \"{var}\"\n") 34 | self.add_used_temp(var) 35 | self.add_var(temp, "string", False, temp) 36 | return temp, None 37 | def fun_entity(self, node, input_nodes): 38 | return self.fun_string(node, input_nodes) 39 | -------------------------------------------------------------------------------- /calc.py: -------------------------------------------------------------------------------- 1 | """ 2 | Basic calculator 3 | ================ 4 | 5 | A simple example of a REPL calculator 6 | 7 | This example shows how to write a basic calculator with variables. 8 | """ 9 | from lark import Lark, Transformer, v_args 10 | 11 | 12 | 13 | 14 | calc_grammar = """ 15 | ?start: sum 16 | | NAME "=" sum -> assign_var 17 | 18 | ?sum: product 19 | | sum "+" product -> test 20 | | sum "-" product -> sub 21 | 22 | ?product: atom 23 | | product "*" atom -> mul 24 | | product "/" atom -> div 25 | 26 | ?atom: NUMBER -> number 27 | | "-" atom -> neg 28 | | NAME -> var 29 | | "(" sum ")" 30 | 31 | %import common.CNAME -> NAME 32 | %import common.NUMBER 33 | %import common.WS_INLINE 34 | 35 | %ignore WS_INLINE 36 | """ 37 | 38 | 39 | @v_args(inline=True) # Affects the signatures of the methods 40 | class CalculateTree(Transformer): 41 | from operator import sub, mul, truediv as div, neg 42 | number = str 43 | 44 | def __init__(self): 45 | self.vars = {} 46 | 47 | def assign_var(self, name, value): 48 | self.vars[name] = value 49 | return value 50 | 51 | def var(self, name): 52 | try: 53 | return self.vars[name] 54 | except KeyError: 55 | raise Exception("Variable not found: %s" % name) 56 | 57 | def test(self, a, b): 58 | print(a, b) 59 | return a + b 60 | 61 | 62 | calc_parser = Lark(calc_grammar, parser='lalr', transformer=CalculateTree()) 63 | calc = calc_parser.parse 64 | 65 | 66 | def main(): 67 | while True: 68 | try: 69 | s = input('> ') 70 | except EOFError: 71 | break 72 | print(calc(s)) 73 | 74 | 75 | def test(): 76 | print(calc("a = 1+2")) 77 | print(calc("1+a*-3")) 78 | 79 | 80 | if __name__ == '__main__': 81 | # test() 82 | main() 83 | -------------------------------------------------------------------------------- /consts.py: -------------------------------------------------------------------------------- 1 | import os 2 | from lark import Token, Lark 3 | import sys 4 | 5 | SCORE_TYPES = ("int", "float", "double", "bool") 6 | MINECRAFT_TYPES = ("bool", "short", "int", "float", "double", "long") 7 | TYPES = ("entity", "nbt", "string") + SCORE_TYPES 8 | SCOREBOARD_NAME = "40planet_num" 9 | STORAGE_NAME = "40planet:value" 10 | NAMESPACE = "__namespace__" 11 | DIGITS = '0123456789' 12 | 13 | INTERPRETE_THESE = ("operator", "call_function", "make_array", "make_nbt", "make_selector", "define_var") 14 | 15 | BUILT_IN_FUNCTION = ("print", "random", "type", "get_score", "get_data", "set_score", "set_data", "round", "del", "append", "is_module", "len", "divide", "multiply") + TYPES 16 | 17 | OPERATOR_ID = { 18 | "+":1, 19 | "-":2, 20 | "*":3, 21 | "/":4, 22 | "%":5, 23 | "==":6, 24 | "!=":7, 25 | ">=":8, 26 | ">":9, 27 | "<=":10, 28 | "<":11, 29 | "!":12, 30 | "member":13, 31 | # ".":14 32 | } 33 | 34 | CNAME = 'CNAME' 35 | INT = 'INT' 36 | ESCAPED_STRING = 'ESCAPED_STRING' 37 | OPERATION = "operation" 38 | 39 | NEW_LINE = "䗻" 40 | 41 | lark_directory = os.path.join(os.path.dirname(__file__), "grammer.lark") 42 | planet_parser = Lark.open(lark_directory) 43 | 44 | 45 | ####################################### 46 | # ERRORS 47 | ####################################### 48 | 49 | def error_as_txt(token, error_name, filename, details, line = ""): 50 | print(type(token)) 51 | with open(filename, "r", encoding="utf-8") as file: 52 | line = file.read().split("\n")[token.line - 1] 53 | 54 | result = f'{error_name}: {details}\n' 55 | result += f'File {filename}, line {token.line}, col {token.column - 1}' 56 | result += "\n\n" + line 57 | if line[-1] != "\n": result += "\n" 58 | result += " " * (token.column - 1) 59 | result += "^" * (token.end_pos - token.start_pos) 60 | return result 61 | 62 | ####################################### 63 | # VARIABLE 64 | ####################################### 65 | 66 | class VariableComet: 67 | def __init__(self, name, temp = "", details = None) -> None: 68 | self.name = name 69 | self.temp = temp 70 | self.details = details 71 | 72 | def __repr__(self): 73 | return f"({self.name}, {self.temp})" 74 | 75 | class Function: 76 | def __init__(self, name, type_, inputs, temp) -> None: 77 | self.name = name 78 | self.type = type_ 79 | self.inputs = inputs 80 | self.temp = temp 81 | def __repr__(self) -> str: 82 | return f"name: {self.name}, temp: {self.temp}, inputs: {self.inputs}" 83 | 84 | class CometToken: 85 | def __init__(self, type_, value, start_pos = None, line = None, column = None, end_line = None, end_column = None, end_pos = None, command = None): 86 | self.tok = Token(type_, value, start_pos, line, column, end_line, end_column, end_pos) 87 | self.command = command 88 | self.type = type_ 89 | self.value = value 90 | self.start_pos = start_pos 91 | self.line = line 92 | self.column = column 93 | self.end_line = end_line 94 | self.end_column = end_column 95 | self.end_pos = end_pos 96 | 97 | def __repr__(self): 98 | return f"CometToken(type:{self.type}, value:{self.value}, command:{self.command})" 99 | 100 | class CometClass: 101 | def __init__(self): 102 | self.method = [] 103 | self.variables = [] -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 아직 안 만들었음.
10 | 언젠간 만들거임.
11 | 12 | 13 | -------------------------------------------------------------------------------- /example/animation.planet: -------------------------------------------------------------------------------- 1 | /scoreboard objectives add 40planet_ani dummy 2 | /scoreboard objectives add 40planet_ani_end_time dummy 3 | 4 | def summon(){ 5 | /# 소환 커맨드 6 | execute(as @e[distance=..0.0001,tag=unset]){ 7 | /scoreboard players set @s ani_end_time 50 8 | /execute on passengers run data modify entity @s interpolation_duration set value 10 9 | } 10 | } 11 | 12 | def tick(){ 13 | execute(as @e[tag=40planet_animation,scores={40planet_ani=0..}]){ 14 | /scoreboard players add @s 40planet_ani 1 15 | /execute if score @s 40planet_ani > @s ani_end_time run scoreboard players reset @s 40planet_ani 16 | /execute if score @s 40planet_ani matches 20 on passengers run function __namespace__:frame_1 17 | /execute if score @s 40planet_ani matches 40 on passengers run function __namespace__:frame_2 18 | } 19 | } 20 | 21 | def frame_1(){ 22 | /execute if entity @s[tag=1] run data modify entity @s transformation.scale set value [1f,2f,1f] 23 | /execute if entity @s[tag=2] run data modify entity @s transformation.translation set value [1f,0f,0f] 24 | } 25 | def frame_2(){ 26 | /execute if entity @s[tag=1] run data modify entity @s transformation.scale set value [1f,1f,1f] 27 | /execute if entity @s[tag=2] run data modify entity @s transformation.translation set value [0f,0f,0f] 28 | } 29 | 30 | # def set_mawang_transformation(){ 31 | # /execute if entity @s[tag=mawang_believer1,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,0.1212,0.0,0.4217,-0.2186,0.3762,-0.0,-0.2186,-0.4217,0.0544,0.0,0.0,0.0,1.0], } 32 | # /execute if entity @s[tag=mawang_believer2,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,0.1131,0.0,0.4199,0.3359,0.3044,-0.0,0.4199,-0.3359,0.1994,0.0,0.0,0.0,1.0], } 33 | # /execute if entity @s[tag=mawang_believer3,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,0.1,0.0,0.0,0.475,0.1238,0.0,0.5937,-0.0,0.0519,0.0,0.0,0.0,1.0], } 34 | # /execute if entity @s[tag=mawang_believer4,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,-0.1137,0.0,0.4217,-0.2186,0.3762,-0.0,-0.2186,-0.4217,0.0544,0.0,0.0,0.0,1.0], } 35 | # /execute if entity @s[tag=mawang_believer5,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,-0.0,-0.1062,0.0,0.4199,0.3359,0.3044,0.0,0.4199,-0.3359,0.1994,0.0,0.0,0.0,1.0], } 36 | # /execute if entity @s[tag=mawang_believer6,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,-0.0956,-0.0,-0.0,0.475,0.1237,0.0,0.5938,0.0,0.0519,0.0,0.0,0.0,1.0], } 37 | # /execute if entity @s[tag=mawang_believer7,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,0.3559,-0.0,-0.4675,0.0841,0.8687,0.0,0.0841,0.4675,-0.0627,0.0,0.0,0.0,1.0], } 38 | # /execute if entity @s[tag=mawang_believer8,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,0.3559,-0.0,-0.4675,0.0841,1.1006,0.0,0.0841,0.4675,-0.1045,0.0,0.0,0.0,1.0], } 39 | # /execute if entity @s[tag=mawang_believer9,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,0.3559,-0.0,-0.4675,0.0841,1.3325,0.0,0.0841,0.4675,-0.1462,0.0,0.0,0.0,1.0], } 40 | # /execute if entity @s[tag=mawang_believer10,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,-0.356,-0.0,-0.4675,0.0841,0.8687,0.0,0.0841,0.4675,-0.0627,0.0,0.0,0.0,1.0], } 41 | # /execute if entity @s[tag=mawang_believer11,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,-0.356,-0.0,-0.4675,0.0841,1.1006,0.0,0.0841,0.4675,-0.1045,0.0,0.0,0.0,1.0], } 42 | # /execute if entity @s[tag=mawang_believer12,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,-0.356,-0.0,-0.4675,0.0841,1.3325,0.0,0.0841,0.4675,-0.1462,0.0,0.0,0.0,1.0], } 43 | # /execute if entity @s[tag=mawang_believer13,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,-0.1185,0.0,0.4675,-0.0841,1.0114,-0.0,-0.0841,-0.4675,-0.0737,0.0,0.0,0.0,1.0], } 44 | # /execute if entity @s[tag=mawang_believer14,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,0.1185,0.0,0.4675,-0.0841,1.0114,-0.0,-0.0841,-0.4675,-0.0737,0.0,0.0,0.0,1.0], } 45 | # /execute if entity @s[tag=mawang_believer15,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,-0.1185,0.0,0.4675,-0.0841,0.7795,-0.0,-0.0841,-0.4675,-0.0319,0.0,0.0,0.0,1.0], } 46 | # /execute if entity @s[tag=mawang_believer16,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,0.1185,0.0,0.4675,-0.0841,0.7795,-0.0,-0.0841,-0.4675,-0.0319,0.0,0.0,0.0,1.0], } 47 | # /execute if entity @s[tag=mawang_believer17,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,-0.1185,0.0,0.4675,-0.0841,0.5476,-0.0,-0.0841,-0.4675,0.0098,0.0,0.0,0.0,1.0], } 48 | # /execute if entity @s[tag=mawang_believer18,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.475,0.0,0.0,0.1185,0.0,0.4675,-0.0841,0.5476,-0.0,-0.0841,-0.4675,0.0098,0.0,0.0,0.0,1.0], } 49 | # /execute if entity @s[tag=mawang_believer19,type=item_display] run data merge entity @s {start_interpolation: 0, interpolation_duration: 10, transformation:[-0.95,0.0,0.0,0.0,0.0,0.8719,-0.3773,1.3902,-0.0,-0.3773,-0.8719,-0.2487,0.0,0.0,0.0,1.0], } 50 | # } -------------------------------------------------------------------------------- /example/health_bar.planet: -------------------------------------------------------------------------------- 1 | 2 | /scoreboard objectives add 40planet_health dummy 3 | /scoreboard objectives add 40planet_pre_health dummy 4 | /scoreboard objectives add 40planet_max_health dummy 5 | 6 | 7 | def tick(){ 8 | /execute as @e[tag=40planet_health_bar] run function __namespace__:tick_entity 9 | execute(as @e[tag=health_bar_display]){ 10 | /scoreboard players set test 40planet_num 0 11 | /execute on vehicle if entity @s[tag=40planet_health_bar] run scoreboard players set test 40planet_num 1 12 | execute(if score "test" "40planet_num" matches 0 at @s){ 13 | /execute on passengers run kill @s 14 | /kill @s 15 | } 16 | } 17 | } 18 | 19 | def detect(){ 20 | /scoreboard players set test 40planet_num 0 21 | /execute on passengers on passengers if entity @s[tag=green] run scoreboard players set test 40planet_num 1 22 | execute(if score "test" "40planet_num" matches 0 at @s){ 23 | /summon interaction ~ ~ ~ {Tags:["health_bar_display","unset"],height:0,width:0,Passengers:[{billboard:"vertical",transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],translation:[-1f,0.8f,0f],scale:[80f,8f,8f]},background:-16122112,Tags:["green"],id:"text_display",interpolation_duration:2,start_interpolation:0},{billboard:"vertical",transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],translation:[-1f,0.8f,-0.001f],scale:[80f,7.9f,7.9f]},background:-65536,Tags:["red"],id:"text_display"},{billboard:"vertical",transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],translation:[0f,1f,0f],scale:[1.5f,1.5f,1.5f]},background:0,Tags:["text"],shadow:1b,id:"text_display"}]} 24 | /ride @n[tag=unset] mount @s 25 | /execute on passengers run tag @s remove unset 26 | } 27 | } 28 | 29 | def set_health(){ 30 | /execute store result score @s 40planet_health run data get entity @s Health 31 | execute(unless score "@s" "40planet_health" = "@s" "40planet_pre_health"){ 32 | /execute store result storage 40planet:value health_bar.max_health float 0.01 run attribute @s minecraft:generic.max_health get 100 33 | var max_health = get_data("storage", "40planet:value", "health_bar.max_health") 34 | var health = get_data("entity", "@s", "Health") 35 | var percentage = health / max_health 36 | execute(on passengers on passengers){ 37 | execute(if entity @s[tag=green]){ 38 | /data modify entity @s start_interpolation set value 0 39 | set_data("entity", "@s", "transformation.scale[0]", percentage * float(80)) 40 | } 41 | execute(if entity @s[tag=text]){ 42 | set_score("@s", "40planet_health", health) 43 | set_score("@s", "40planet_max_health", max_health) 44 | /data merge entity @s {text:'["",{"score":{"name":"@s","objective":"40planet_health"},"color":"green"},{"text":"/","color":"green"},{"score":{"name":"@s","objective":"40planet_max_health"},"color":"green"}]'} 45 | } 46 | } 47 | } 48 | 49 | /scoreboard players operation @s 40planet_pre_health = @s 40planet_health 50 | } 51 | 52 | def tick_entity(){ 53 | execute(if entity @s[type=player]){ 54 | /tellraw @s {"text":"플레이어에게는 체력바를 표시할 수 없습니다", "color":"red"} 55 | return 0 56 | } 57 | detect() 58 | set_health() 59 | } -------------------------------------------------------------------------------- /example/test.planet: -------------------------------------------------------------------------------- 1 | def is_correct_key(){ 2 | var player_id = get_score("@s","id") 3 | /$data modify storage minecraft:fish temp append from storage minecraft:fish q_$(player_id)[0] 4 | 5 | execute(if block ~ ~ ~ trapdoor[open=false]{test:"asdf"}) 6 | 7 | execute(if predicate minecraft:a if data storage fish {temp:"A"}) { return 1 } 8 | execute(if predicate minecraft:s if data storage fish {temp:"S"}) { return 1 } 9 | execute(if predicate minecraft:d if data storage fish {temp:"D"}) { return 1 } 10 | execute(if predicate minecraft:w if data storage fish {temp:"W"}) { return 1 } 11 | return 0; 12 | } -------------------------------------------------------------------------------- /example/test2.planet: -------------------------------------------------------------------------------- 1 | var asdf = 1 -------------------------------------------------------------------------------- /example/test3.planet: -------------------------------------------------------------------------------- 1 | import test2 2 | 3 | print(test2.asdf) -------------------------------------------------------------------------------- /example/test_.planet: -------------------------------------------------------------------------------- 1 | execute(as @a){ 2 | var i = 0 3 | var inventory = get_data("entity", "@s", "Inventory") 4 | /execute store result score len num run data get entity @s Inventory 5 | var len = get_score("len", "num") 6 | while(i < len){ 7 | var item = inventory[i] 8 | #if (대충 아이템 조건) 9 | var slot = inventory[i].Slot 10 | /item replace entity @s container.^slot& with <아이템> 11 | i = i + 1 12 | } 13 | } -------------------------------------------------------------------------------- /grammer.lark: -------------------------------------------------------------------------------- 1 | %import common.CNAME 2 | //%import common.FLOAT 3 | FLOAT: /\d+\.\d+/ 4 | //%import common.INT 5 | INT: /\d+/ 6 | // %import common.ESCAPED_STRING 7 | ESCAPED_STRING: /"([^"\\\n]|\\.)*"/ 8 | | /'([^'\\\n]|\\.)*'/ 9 | // | /[a-zA-z]+/ 10 | %import common.WS_INLINE 11 | %import common.WS 12 | %import common.NEWLINE 13 | 14 | 15 | start: (statement eol*)* statement? 16 | 17 | ?statement.-998: minecraft_command | command_macro 18 | | eol 19 | | condition 20 | | function_def 21 | | variable_def 22 | | variable_set 23 | | if_statement 24 | | while_statement 25 | | execute 26 | | return_ 27 | | break_ 28 | | import_statement 29 | // | class_def 30 | 31 | minecraft_command: /\/[^\$][^\n]*/ 32 | command_macro: "/$" ( macro_ | word )+ 33 | // minecraft_command.10: "/" (macro | word)+ eol 34 | macro_: "$(" CNAME ")" 35 | word.1: /(\\\$|[^\n\$^䗻])+/ 36 | 37 | new_line.2: /\n/ 38 | ?eol: new_line | ";" | "䗻" 39 | 40 | // 중괄호 블럭 41 | block: "{" statement* "}" 42 | | statement 43 | 44 | parameter_list: _seperated{parameter, ","} 45 | ?parameter: "var" CNAME 46 | arguments: _seperated{argument, ","} 47 | argument: condition 48 | | selector //-> selector 49 | 50 | 51 | // import문 52 | import_statement: "import" CNAME 53 | 54 | //함수 선언, 실행 55 | //-------------------------------------------------------------- 56 | function_def: "def" CNAME "(" [parameter_list] ")" block 57 | function_call: CNAME "(" [arguments] ")" 58 | | CNAME "." CNAME "(" [arguments] ")" -> method 59 | 60 | 61 | 62 | //변수 설정 63 | //-------------------------------------------------------------- 64 | variable_def: "var" CNAME 65 | variable_set: CNAME set_value 66 | | variable set_value 67 | | variable_def set_value 68 | ?set_value : "=" condition 69 | 70 | //사칙연산 71 | //-------------------------------------------------------------- 72 | 73 | // expression = 어떠한 값 (변수, 사칙연산 등) 74 | ?expression: expression "+" term -> add 75 | | expression "-" term -> sub 76 | | term 77 | 78 | ?term: term "*" factor -> mul 79 | | term "/" factor -> div 80 | | term "%" factor -> mod 81 | | factor 82 | 83 | ?factor: value 84 | | "-" factor -> neg 85 | | "(" condition ")" 86 | 87 | 88 | //멤버연산 89 | //-------------------------------------------------------------- 90 | member_operation: variable "[" expression "]" 91 | | array "[" INT "]" 92 | | array "[" /[+-]\d+/ "]" 93 | dot_operation: variable "." (CNAME | ESCAPED_STRING) 94 | | nbt "." (CNAME | ESCAPED_STRING) 95 | | dot_operation "." no_dot_minecraft_id 96 | no_dot_minecraft_id : CNAME ":" CNAME 97 | 98 | //값 토큰 설정 99 | //-------------------------------------------------------------- 100 | _seperated{x, sep}: (x (sep x)*)? 101 | 102 | ?variable.-1000: dot_operation 103 | | member_operation 104 | | CNAME 105 | | pointer 106 | | address 107 | | function_call 108 | // | method 109 | pointer: "*" "(" variable ")" 110 | | "*" variable 111 | address: "&" "(" variable ")" 112 | | "&" variable -> address 113 | 114 | array.-9999: "[" _seperated{condition, ","} "]" 115 | nbt: "{" _seperated{pair, ","} "}" 116 | ?pair: CNAME ":" condition 117 | | ESCAPED_STRING ":" condition 118 | 119 | ?number:/\d+[bdf]?/ 120 | | /\d+\.\d+[bdf]?/ 121 | | /\.\d+[bdf]?/ 122 | ?value: ESCAPED_STRING 123 | | variable 124 | | FLOAT 125 | | INT 126 | | array 127 | | nbt 128 | | number 129 | 130 | 131 | //키워드 설정 132 | //-------------------------------------------------------------- 133 | return_: "return" condition 134 | break_.10: "break" 135 | 136 | //조건문, 반복문 설정 137 | //-------------------------------------------------------------- 138 | if_statement: "if" "(" condition ")" block ("else" block)? 139 | while_statement: "while" "(" condition ")" block 140 | 141 | 142 | //논리연산 143 | //-------------------------------------------------------------- 144 | ?logic_operation : expression 145 | | expression "==" expression -> equal 146 | | expression ">" expression -> bigger 147 | | expression ">=" expression -> bigger_equal 148 | | expression "<" expression -> smaller 149 | | expression "<=" expression -> smaller_equal 150 | | expression "!=" expression -> not_equal 151 | | "!" "(" logic_operation ")" -> not_operation 152 | ?condition: logic_operation 153 | | condition "and" condition -> and_operation 154 | | condition "or" condition -> or_operation 155 | 156 | 157 | // execute 설정 158 | //-------------------------------------------------------------- 159 | ?minecraft_number: /[+-]?(\d+(\.\d+)?|\.\d+)/ 160 | ?minecraft_range: minecraft_number 161 | | /[+-]?(\d+(\.\d+)?|\.\d+)\.\./ 162 | | /\.\.[+-]?(\d+(\.\d+)?|\.\d+)/ 163 | | /[+-]?(\d+(\.\d+)?|\.\d+)\.\.[+-]?(\d+(\.\d+)?|\.\d+)/ 164 | ?minecraft_id: MINECRAFT_NAME ":" MINECRAFT_NAME 165 | | MINECRAFT_NAME 166 | ?minecraft_id_tag: "#" minecraft_id 167 | | minecraft_id 168 | MINECRAFT_NAME: /[a-zA-Z0-9_.]+/ 169 | MINECRAFT_NAME_NOT_DOT: /[a-zA-Z0-9_]+/ 170 | ?json_pair: /"([^"\\]|\\.)*"/ ":" json_value 171 | ?json_value: /"([^"\\]|\\.)*"/ 172 | | number 173 | | "true" 174 | | "false" 175 | | "{" _seperated{json_pair, ","} "}" -> json_ 176 | 177 | ?selector: /@[parsen]/ ("[" _seperated{selector_parameter, ","} "]")? 178 | | /"?[a-z\d]+-[a-z\d]+-[a-z\d]+-[a-z\d]+-[a-z\d]+"?/ 179 | selector_parameter: /tag=/ (/!/? MINECRAFT_NAME)? 180 | | /advancements=/ minecraft_id_tag 181 | | /distance=/ minecraft_range 182 | | /d[xyz]=/ INT 183 | | /gamemode=/ /!?(?:adventure|creative|survival|spectator)/ 184 | | /level=/ minecraft_range 185 | | /limit=/ INT 186 | | /name=/ /!/? MINECRAFT_NAME 187 | // | "nbt=" /!/? nbt -> selector_nbt 188 | | /predicate=/ minecraft_id 189 | | "scores=" "{" (MINECRAFT_NAME "=" minecraft_range)? ("," MINECRAFT_NAME "=" minecraft_range)* "}" -> scores 190 | | /sort=/ /(arbitrary|furthest|nearest|random)/ 191 | | /team=/ MINECRAFT_NAME 192 | | /[xyz]=/ minecraft_number 193 | | /[xy]_rotation=/ minecraft_range 194 | | /type=/ /!/? minecraft_id_tag 195 | 196 | 197 | 198 | ?coordinate_set: coord coord coord 199 | | /\^([+-]?(\d+(\.\d+)?|\.\d+))?/ /\^([+-]?(\d+(\.\d+)?|\.\d+))?/ /\^([+-]?(\d+(\.\d+)?|\.\d+))?/ 200 | 201 | ?coord: /~([+-]?(\d+(\.\d+)?|\.\d+))?/ 202 | | minecraft_number 203 | 204 | execute: "execute" "(" execute_parameter+ ")" block 205 | execute_parameter: /as/ selector 206 | | /if/ execute_if 207 | | /unless/ execute_if 208 | | /positioned/ execute_positioned 209 | | /in/ minecraft_id_tag 210 | | /align/ /(xyz|xzy|yxz|yzx|zxy|zyx|xy|yx|xz|zx|yz|zy|x|y|z)/ 211 | | /anchored/ /(eyes|feet)/ 212 | | /at/ selector 213 | | /facing/ execute_facing 214 | | /on/ /(attacker|controller|leasher|origin|owner|passengers|target|vehicle)/ 215 | | /rotated/ execute_rotated 216 | | /store/ /(success|result)/ execute_store 217 | | /summon/ minecraft_id 218 | 219 | ?execute_positioned: coordinate_set 220 | | /over/ /(motion_blocking|motion_blocking_no_leaves|ocean_floor|world_surface)/ 221 | | /as/ selector 222 | ?execute_rotated: coord coord 223 | | /as/ selector 224 | 225 | ?execute_facing: coordinate_set 226 | | /entity/ selector /(eyes|feet)/ 227 | 228 | ?nbt_dir: MINECRAFT_NAME_NOT_DOT 229 | | ESCAPED_STRING 230 | | nbt_dir /\[[+-]?\d+\]/ 231 | | nbt_dir /\./ (MINECRAFT_NAME_NOT_DOT | ESCAPED_STRING) 232 | ?execute_store: execute_store_list nbt_dir /(byte|double|float|int|long|short)/ minecraft_number 233 | | /score/ (selector|MINECRAFT_NAME) MINECRAFT_NAME 234 | ?execute_store_list: block_entity 235 | | /bossbar/ minecraft_id 236 | | /score/ (selector|MINECRAFT_NAME) MINECRAFT_NAME 237 | | /storage/ minecraft_id 238 | 239 | nbt_pair: "{" _seperated{pair, ","} "}" 240 | ?execute_if: /predicate/ execute_if_predicate 241 | | /boime/ coordinate_set minecraft_id_tag 242 | | /block/ coordinate_set execute_if_block 243 | | /blocks/ coordinate_set coordinate_set coordinate_set /(all|masked)/ 244 | | /data/ execute_if_data (nbt_dir|dot_operation|member_operation|nbt_pair) 245 | | /dimension/ minecraft_id_tag 246 | | /entity/ selector 247 | | /function/ execute_if_function 248 | | /items/ block_entity item_slot item 249 | | /loaded/ coordinate_set 250 | | /score/ scoreboard execute_if_score 251 | ?execute_if_predicate: "{" _seperated{json_pair, ","} "}" 252 | | minecraft_id 253 | ?execute_if_data: block_entity 254 | | /storage/ minecraft_id 255 | execute_if_function: minecraft_id_tag 256 | | if_function_block 257 | if_function_block: "{" statement* "}" 258 | ?block_entity: /block/ coordinate_set 259 | | /entity/ selector 260 | ?item_slot: /(container|enderchest|horse|hotbar|inventory|player\.crafting|villager)\.(\d+|\*)/ 261 | | /contents/ 262 | | /weapon/ 263 | | /weapon\.(?:\*|mainhand|offhand)/ 264 | | /horse\.(?:chest|saddle)/ 265 | | /armor\.(?:\*|body|chest|feet|head|legs)/ 266 | | /player.cursor/ 267 | item: (/\*/ | minecraft_id_tag) /\[.*\]/? 268 | ?execute_if_score: /matches/ minecraft_range 269 | | /(>=|<=|>|=|<)/ scoreboard 270 | ?scoreboard: (selector|ESCAPED_STRING|MINECRAFT_NAME) (ESCAPED_STRING|MINECRAFT_NAME) 271 | // execute if block ~ ~ ~ stone_button[facing=north,face=floor,powered=false] 272 | // execute if block ~ ~ ~ barrel[open=true]{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]} 273 | // 이런거 감지하는거 274 | ?block_state_pair: CNAME "=" CNAME 275 | block_state: "[" _seperated{block_state_pair, ","} "]" 276 | execute_if_block: minecraft_id_tag 277 | | minecraft_id_tag block_state 278 | | minecraft_id_tag block_state nbt_pair 279 | 280 | 281 | // TODO : class 설정 282 | //-------------------------------------------------------------- 283 | // class_def: "class" CNAME "{" ((function_def | variable_def) eol?)* "}" 284 | // method: variable "." CNAME "(" [arguments] ")" 285 | 286 | 287 | 288 | %ignore WS_INLINE 289 | // %ignore WS 290 | %ignore /#[^\n;]*/ // 주석 291 | %ignore /\n/ -------------------------------------------------------------------------------- /log.md: -------------------------------------------------------------------------------- 1 | # 2024/05/15 1.0 2 | - 릴리즈 3 | # 2024/05/20 1.1 4 | - 한글이 깨지는 것 버그 고침 5 | - print에서 지역변수가 인식되던 버그 고침 6 | # 2024/05/31 2.0 7 | - 자료형이 더욱 유동적으로 변함 8 | - 변수 선언 키워드 변경 9 | - ("int", "float", "double", "string", "entity") -> var 10 | - 함수의 리턴 자료형 설정 불가능 11 | - get_data의 4번째 인자가 삭제됨 12 | - 3개의 인자만 받도록 변경됨 13 | # 2024/06/03 2.1 14 | - float(a)가 "data modify storage 40planet:value 1 set value a"로 컴파일 되던 오류 수정 15 | - A가 B를 import하고 B가 A를 import 했을 때 에러나는 현상 오류 수정 16 | # 2024/06/05 2.2 17 | - 버전 선택 기능 추가 18 | # 2024/06/06 2.3 19 | - 아래와 같은 상황에서 break, return이 정상작동 하지 않던 문제를 해결함 20 | ``` 21 | def test(){ 22 | execute(as @a){ 23 | return 0 24 | } 25 | print("return dosen't worked") 26 | } 27 | ``` 28 | # 2024/06/12 2.4 29 | - 아래와 같은 상황에서 break, return이 정상작동 하지 않던 문제를 해결함 30 | ``` 31 | def test(){ 32 | if(1 == 1){ 33 | if(1 == 1){ 34 | return 1 35 | print("asdf") 36 | } 37 | } 38 | } 39 | ``` 40 | - 이중배열 선언 시 오류가 나던 문제를 해결함 41 | - `test.asdf.fdsa`와 같이 "." 연산자로 2번 이상 데이터 접근 시 오류가 나던 문제를 해결함 42 | # 2024/06/13 2.5 43 | - 함수를 정의하고 안에 아무것도 적지 않았을 경우 에러가 나던 문제를 해결함 44 | - `+` 연산으로 배열에 원소를 추가할 수 있음 45 | ``` 46 | var arr = [] 47 | arr = arr + 1 48 | ``` 49 | - del 내장함수 추가 50 | - basic 데이터팩이 일부 변경 됨 51 | # 2024/06/15 2.6 52 | - 1.20 버전에서 `execute(if items)` 구문을 쓰면 에러가 나도록 바뀜 53 | - 1.21 버전을 선택할 수 있음 54 | # 2024/06/15 2.6.1 55 | - 1.20.4 버전에서 `execute(if items)` 구문을 쓰면 에러가 나도록 바뀜 56 | - 1.20.4, 1.20.6, 1.21 버전을 선택할 수 있음 57 | # 2024/06/15 2.6.2 58 | - `basic.zip` 내의 `functions` 폴더 명이 `function`로 수정됨 59 | - `basic.zip`이 버전에 따라 달라짐에 따라 `basic_1.20.zip`, `basic_1.21.zip`으로 나뉨 60 | - 내장함수 `string`에 변수를 넣었을 경우에 데이터팩에 오류가 나던 현상이 해결됨 61 | # 2024/06/15 2.7 62 | - `__namespace__`를 활용하여 마크 명령어를 입력할 때에 네임스페이스를 쓸 수 있게 됨 63 | ``` 64 | def dumb_function(var a){ 65 | return a 66 | } 67 | 68 | /function __namespace__:dumb_function 69 | ``` 70 | # 2024/06/16 2.8 71 | - `+` 연산자로 원소를 추가할 수 없게 됨 72 | - `append` 내장함수가 추가됨 73 | `append(arr, element)` 74 | ``` 75 | var arr = [] 76 | append(arr, 1) 77 | var test = 2 78 | append(arr, test) 79 | print(arr) 80 | ``` 81 | ``` 82 | [1, 2] 83 | ``` 84 | - `string` 내장함수가 제대로 작동하지 않던 오류를 해결함 85 | - `1.20.6`을 선택했을 때에 폴더명이 `function`으로 생성되던 오류를 해결함 86 | # 2024/06/17 2.8.1 87 | - `is_module()` 내장함수 추가 88 | ``` 89 | if(is_module()){ 90 | print("this is not main") 91 | } 92 | ``` 93 | - `!` 안에 함수가 들어간 경우 에러가 나던 오류를 해결함 94 | - `!` 연산이 실질적으로 아무것도 수행하지 않던 오류를 해결함 95 | # 2024/06/17 2.8.2 96 | - 모듈 내의 변수에 접근할 수 없던 오류를 해결함 97 | - `break`, `return`을 감지하는 명령어가 중복되어 생성되는 오류를 해결함 98 | # 2024/06/17 2.9 99 | - 다차원 배열의 원소에 접근이 불가능하던 오류를 해결함 100 | # 2024/06/22 2.9.1 101 | - `.`연산자를 통해 변수의 요소에 접근 할 때 접근이 안 되던 오류를 해결함 102 | - `README.md`의 몇몇 오타 수정 103 | - `break`, `return`을 판단하는 변수가 초기화가 안 되던 오류를 해결함 104 | - `execute if` 구문에 `data` 추가 105 | # 2024/06/30 2.10 106 | - `del` 내장함수가 삭제된 값을 반환함 107 | - 함수의 인자가 제대로 전달되지 않던 오류를 수정함 108 | - `README.md`에 `del` 내장함수 설명을 적음 109 | - 몇몇 연산에 변수를 넣으면 제대로 작동하지 않던 오류를 해결함 110 | - `set_data` 111 | - 멤버연산 `[]` 112 | - `false`, `true` 추가 113 | - `len` 추가 114 | # 2024/07/10 2.10.1 115 | - `README.md` 영어로 변경 116 | - `README_kr.md` 추가 117 | - `README.md`의 `random` 내용 변경 118 | # 2024/07/16 2.10.2 119 | - `execute( if data var )` 형식에서 var에 점 연산이 있을 경우 에러가 나던 문제를 해결함 120 | - nbt 자료형의 키값에 문자열을 넣으면 에러가 나던 문제를 해결함 121 | - `3b`와 같은 `byte` 자료형을 `3`으로 컴파일 하던 에러를 해결함 122 | - print에 선택인자를 넣어도 선택된 엔티티가 출력되지 않던 에러를 해결함 123 | - `basic`의 논리 연산에서 값이 이상하게 나오던 에러를 해결함 124 | - 변수를 실행시키려 할 때, 에러가 나지 않던 것을 해결함 125 | ``` 126 | var a = 1 127 | a() 128 | ``` 129 | # 2024/07/16 2.11 130 | - 조건에 연산을 쓰지 않고 `while(var)`, `if(var)`의 형태로 적는 것이 가능해짐 131 | - `README.md`에 관련 내용 추가 132 | # 2024/07/17 133 | - `Comet Highlighter` 익스텐션 업데이트 134 | - `true`, `false` 키워드 추가 135 | - `unless` 키워드 추가 136 | # 2024/07/17 2.11.1 137 | - `break`를 사용했을 때 데이터팩이 고장나던 오류 수정 138 | - `while`의 조건에 변수를 넣었을 떼 2 이상인 경우에 반복이 안 되던 오류 수정 139 | - `return`이 2개 이상 있을 때 오류가 나던 현상 해결 140 | - `float`의 곱셈에서 수가 100배가 되던 현상 해결 141 | - `-`연산이 코드에 들어갈 경우 프로그램이 멈추던 오류 해결 142 | # 2024/07/23 2.11.2 143 | - 아래와 같이 `nbt`의 `value` 부분에 연산자 또는 배열을 넣을 경우 에러가 나던 현상 해결 144 | ``` 145 | var test = { 146 | arr: [1, 2, 3], 147 | temp: 1b 148 | } 149 | var test2 = { 150 | test_arr: test.arr 151 | } 152 | ``` 153 | - `.` 연산 이후에 멤버 접근 연산을 수행하려 할 때 에러가 나던 현상 해결 154 | ``` 155 | var laundry = { 156 | arr: [1, 2, 3], 157 | temp: 1b 158 | } 159 | 160 | print(laundry.arr[0]) 161 | print(laundry.arr[0].test) 162 | ``` 163 | # 2024/08/05 2.11.3 164 | - `README`의 `execute if data` 부분의 오류 수정 165 | ``` 166 | execute(if data storage "temp:test" id){ 167 | ``` 168 | ``` 169 | execute(if data storage "temp:test" "id"){ 170 | ``` 171 | - nbt를 만들 때 빈 값(`{}`)이 들어가면 에러가 나던 현상 해결 172 | - nbt를 만들 때 `,`가 없을 때의 에러메시지 수정 173 | ``` 174 | Invalid Syntax: : was not defined operator 175 | ``` 176 | ``` 177 | Invalid Syntax: prior "," is missing 178 | ``` 179 | # 2024/08/08 2.11.4 180 | - `if`, `else` 등을 중괄호 없이 적었을 때 제대로 인식이 안 되던 오류 수정 181 | ``` 182 | if(num == 1) 183 | print(1) 184 | else if(num == 2) 185 | print(2) 186 | else if(num == 3) 187 | print(3) 188 | else 189 | print("예측 실패") 190 | ``` 191 | # 2024/08/16 2.12 192 | - `double` 내장함수가 작동하지 않던 오류 수정 193 | - 버전에 `1.21.1` 추가 194 | - 선택한 버전에 따라 `pack.mcmeta`의 버전이 바뀌도록 수정 195 | # 2024/08/23 2.13 196 | - `int`, `float`, `double`끼리의 연산이 가능해짐 197 | - `{}`로 묶인 부분이 파일의 마지막 글자일 때, 무한 로딩이 걸리던 버그를 해결함 198 | # 2024/08/31 2.14 199 | - `if block`이 문법을 제대로 지켜도 에러가 나던 현상을 해결함 200 | - `devide`, `multiply` 추가 201 | - 스토리지에 저장되는 정보에 네임스페이스를 추가함 202 | - ex) `pack_var_temp10` 203 | - 스토리지에 저장되는 경로가 data 아래로 옮겨짐 204 | - `execute` 구문 내의 모든 좌표는 문자열로 적어야 합니다 205 | ``` 206 | execute(positioned 0 0 0){...} 207 | ``` 208 | ``` 209 | execute(positioned "0 0 0"){...} 210 | ``` 211 | - `execute` 구문을 한 줄에 적을 필요가 없게 됨 212 | ``` 213 | execute(as 214 | @a){ 215 | /say a 216 | } 217 | ``` 218 | - `execute` 구문의 `if function` 성능이 강화됨 219 | ``` 220 | def test(){ 221 | return 1 222 | } 223 | 224 | execute(if function { 225 | return test() 226 | }){ 227 | print("성공!") 228 | } 229 | ``` 230 | # 2024/09/24 2.14.1 231 | - `execute if score <플레이어> <스코어보드> matches`의 범위가 제대로 인식되지 않던 오류 수정 232 | - `execute if items`에서 아이템의 아이디 대신 `*`을 넣었을 경우, 에러가 나던 현상 해결 233 | - 함수의 `return`이 제대로 작동하지 않던 오류 해결 234 | - 실행 중 나오는 에러메시지에 `Runtime Error : ` 문구 추가 235 | - nbt와 배열을 생성할 때의 성능 개선 236 | # 2024/09/25 버전업 없음 237 | - `README.md`에 연산자의 자료형에 관한 내용 추가 238 | - 연산의 결과는 연산자의 뒤쪽 피연산자를 따라갑니다 239 | - ex) 0.3 * 1 = 0 240 | # 2024/09/30 버전업 없음 241 | - `README`에 `float`와 `double` 자료형의 경우엔 사칙연산에서 소수점 아래 3번째 자리부터 날라간다는 내용 추가 242 | - 몇몇 f format으로 쓰인 부분을 + 연산자로 바꿈 243 | - `README`에 혜성 1강 링크 추가 244 | # 2024/10/01 2.15 245 | - cli 추가 및 `README`에 관련 내용 추가 246 | # 2024/10/02 2.15.1 247 | - `var t = 2.5`와 같이 소수가 대입이 제대로 되지 않던 오류 수정 248 | - `devide` $\to$ `divide` 내장함수 이름 변경 249 | - 2024/10/02 oein님의 풀리퀘 merge 250 | - 정형화된 CLI 로그 추가 251 | - 에러 메시지, 실행 시 나오는 아이콘 등 252 | - 38번째 줄에 있는 `verboseLevel = LOGLEVEL["DEBUG"]`의 `"DEBUG"` 부분을 변경하여 로그에 표시될 내용을 변경할 수 있음 253 | # 2024/10/23 2.16 254 | - 모듈 내의 정의되지 않은 함수를 호출 할 때에 에러메시지가 안 뜨던 오류 수정 255 | - 아래와 같이 `if predicate`를 작성 시, 에러가 나는 현상 수정 256 | ``` 257 | if predicate {"condition":"minecraft:entity_properties","entity":"this","predicate":{"vehicle":{}}} 258 | ``` 259 | - 엔티티가 들어갈 자리에 이름을 직접 적거나 UUID를 작성한 경우에 에러를 내던 오류 수정 260 | - import 된 파일에서 다시 import 한 파일의 함수를 호출하는 경우, 호출이 안 되던 오류 수정 261 | - 반복문 안에서 return을 쓸 경우, 함수 탈출이 안 되던 오류 수정 262 | - 아래와 같이 `if block`을 작성 시, 에러가 나는 현상 발견 263 | ``` 264 | if block "~ ~ ~" chest[facing=east] 265 | ``` 266 | - `if items`에서 `weapon.offhand` 슬롯을 감지하려고 하면 에러가 나던 현상 수정 267 | - 선택 가능한 버전에 `1.21.2` 추가 268 | # 2024/11/24 2.16.1 269 | - tkinter 모듈의 `Variable`과 혜성의 `Variable`이 충돌하여 에러가 나던 현상 해결 270 | - `Variable` $\to$ `VariableComet`으로 클래스 명을 바꿔 해결 271 | # 2024/11/26 2.17 272 | - `del(a)`와 같이 del 함수에 변수를 넘겨줬을 경우 data remove 명령어가 제대로 작성되지 않던 오류 해결 273 | - 컴파일 할 때 데이터팩 전체를 지우고 새로 생성하는 것이 아닌, function 폴더만 지우고 새로 생성하는 것으로 바뀜 274 | - 입력한 네임스페이스 아래의 loot_table, recipe 등을 건드리지 않음 275 | # 2024/11/28 276 | ``` 277 | var a = @p 278 | print(a) 279 | print(@p) 280 | ``` 281 | - 위와 같은 코드를 컴파일 하면 두 print의 출력에 차이가 발생하는 문제를 인지함 282 | # 2024/12/27 3.0b 283 | - 포인터 추가 284 | - Lark를 이용해 내부 구조 리마스터 285 | - 이미 정의된 변수를 다시 정의하려 했을 때 에러가 발생하지 않게 됨 286 | - execute의 문법이 다수 개정됨 287 | - `"~ ~ ~"` $\to$ `~ ~ ~` 288 | - `if score "@s" "40planet_num"` $\to$ `if score @s 40planet_num` 289 | - 이 경우엔 전자도 가능하지만, 후자도 가능하도록 바뀜 290 | - 마인크래프트의 execute 명령어를 그대로 갖다 박아도 무사히 작동되도록 변경함 291 | - 매크로 문법이 변경됨 292 | - `/say ^variable&` $\to$ `/$say $(variable)` 293 | - 본래의 마크의 매크로 문법을 살림 294 | - 0b, 1b 등 마크 자료형 문제 해결 295 | - 엔티티 자료형 삭제 296 | ### 아직 정식으로 3.0을 릴리즈 한건 아님! 297 | # 2024/12/27 298 | - 늘 그렇듯 if, execute, while에서의 return, break 에러 수정 299 | # 2025/01/01 300 | - 3.0 베타 릴리즈 301 | - `{}`로 nbt를 생성할 때 오류가 나던 현상 해결 302 | - 창모드에서 컴파일이 불가능하던 에러 해결 303 | # 2025/01/06 3.0.1b 304 | - `/$$(a) $(b)`를 `$(a)$(b)`와 같이 컴파일하던 에러 해결 305 | - 함수의 매개변수로 넘어간 연산을 처리하지 않던 에러 해결 306 | - `multiply` 내장함수가 아예 작동하지 않던 에러 해결 307 | # 2025/01/10 3.0.2b 308 | - pyinstaller로 패키징 했을 때 abspath가 정상작동하지 않아 에러가 나던 현상 해결 309 | - `and`, `or`, `!` 연산 사용 시 에러나던 현상 해결 310 | - 빈 배열(`[]`) 선언 시 에러나던 현상 해결 311 | # 2025/01/13 3.0.3b 312 | - 아래와 같이 배열의 모든 원소에 대해 반복문을 돌리려고 할 때, 무한루프가 발생하는 오류 해결 313 | ``` 314 | while(arr[0]){ 315 | print(arr[0]) 316 | del(arr[0]) 317 | } 318 | ``` 319 | - while 내부에서 break를 쓰면 while에서까지 break가 동작하는 오류 해결 320 | - 이전 실행의 break의 스코어보드가 이후 실행의 break에 영향을 끼치는 오류 해결 321 | - 대부분의 상황에서 논리연산자가 제대로 작동하지 않던 오류 해결 322 | # 2025/01/18 3.0.4b 323 | - `execute(as @a at @s) /$$(a)`와 같이 "/$"가 맨 처음에 오지 않을 때 매크로가 정상작동하지 않던 오류 해결 324 | - `item.components."minecraft:custom_data"`과 같이 `.`연산에서 문자열을 쓰고자 하면 에러가 나던 현상 해결 325 | - 배열에 음수인덱스 추가 326 | - 아래와 같은 상황에서 문자열을 정상적으로 인식하던 오류 해결 327 | ``` 328 | a = "as 329 | df" 330 | ``` 331 | - 매크로를 사용한 커맨드에서 `\$`로 "$"를 입력할 수 있는 기능이 추가됨 332 | # 2025/01/30 3.0.5b 333 | - `/$$(command)`와 같이 명령어의 처음부터 매크로를 사용하면 실행이 안 되던 에러 해결 334 | - 매크로를 컴파일하는 과정에서의 속도 향상 335 | # 2024/02/03 3.0 336 | - `del(data)`라는 코드가 있으면 인게임에서 많은 렉이 걸리고 튕기는 현상 해결 337 | - 배열을 만들 때 같은 배열을 두번 만드는 현상 해결 338 | # 2025/02/04 3.0.1 339 | - Linux 환경에서 `\`로 인한 경로 에러가 나던 것 수정 340 | - `README.md`에서 입문자가 읽기 더 편하게 바뀜 341 | - `README.md`, `README_kr.md` $\to$ `README_en.md`, `README.md`로 바뀜 342 | # 2025/02/19 3.1 343 | - -l 옵션으로 로그 레벨 조정 가능 344 | - DEBUG 345 | - INFO 346 | - WARNING 347 | - ERROR 348 | - CRITICAL 349 | - FATAL 350 | - LOG 351 | - 태그나 스코어보드 이름에 `.`이 들어가도 에러가 나지 않음 352 | - 명령어가 너무 길어지고 같은 변수를 반복해서 매크로로 사용할 경우 매크로가 정상작동하지 않는 오류 해결 353 | - 최적화를 진행, 내 노트북에선 약 3배 가량 빨라짐 354 | # 2025/03/14 3.1.1 355 | - 일부 마크 문법이 혜성에서 에러를 내던 오류 해결 356 | - `SelectedItem.components.minecraft:custom_data` 357 | - 아래와 같이 작성되면 nbt 데이터가 제대로 생성되지 않던 오류 해결 358 | ``` 359 | { 360 | function: info.function, 361 | owner_id: get_score("@s", "40planet_id"), 362 | enabled: 1b 363 | } 364 | ``` 365 | - 같은 .planet 파일을 서로 다른 파일에서 import 했을 때 에러가 나던 오류 해결 366 | # 2025/04/07 3.1.2, 3.1.3 367 | - `return`이 아예 작동하지 않던 오류 해결 368 | - `set_data`, `set_score`의 마지막 인수에 함수를 사용했을 때 함수가 두번씩 실행되던 오류 해결 369 | # 2025/04/14 3.2 370 | - import한 다른 파일의 전역변수에 접근 가능하게 됨 371 | # 2025/04/15 3.2.1, 3.2.2 372 | - `if block`의 문법오류 해결 373 | - block_state : `if block ~ ~ ~ stone_button[facing=north,face=floor,powered=false]` 374 | - nbt : `if block ~ ~ ~ barrel[open=true]{Items:[{Slot:26b,id:"minecraft:stone",count:1}]}` 375 | # 2025.05.18 3.2.3 376 | - `divide`에서 결과값이 항상 양수던 에러 해결 377 | # 2025.06.08 3.2.4 378 | - `if data storage fish {temp:"W"}`와 같이 if data 문법 추가 -------------------------------------------------------------------------------- /logger.py: -------------------------------------------------------------------------------- 1 | 2 | ####################################### 3 | # LOGGER 4 | ####################################### 5 | 6 | import time 7 | 8 | # 수가 더 클 수록 더 많이 표시되는 것 9 | LOGLEVEL = { 10 | "DEBUG": 256, 11 | "INFO": 128, 12 | "WARNING": 64, 13 | "ERROR": 32, 14 | "CRITICAL": 16, 15 | "FATAL": 8, 16 | "LOG": 4, 17 | } 18 | 19 | # verboseLevel = LOGLEVEL["DEBUG"] 20 | 21 | class L: 22 | def __init__(self): self.verboseLevel = LOGLEVEL["INFO"] 23 | def prCyan(self, skk): return "\033[96m{}\033[00m".format(skk) 24 | def prYello(self, skk): return "\033[93m{}\033[00m".format(skk) 25 | def prRed(self, skk): return "\033[91m{}\033[00m".format(skk) 26 | def prGreen(self, skk): return "\033[92m{}\033[00m".format(skk) 27 | def prPurple(self, skk): return "\033[95m{}\033[00m".format(skk) 28 | def prGray(self, skk): return "\033[90m{}\033[00m".format(skk) 29 | 30 | def getTimeSTR(self): 31 | return time.strftime("%H:%M:%S", time.localtime()) 32 | 33 | def print(self, scope: str, message, level: int = LOGLEVEL["DEBUG"]): 34 | if level > self.verboseLevel: 35 | return 36 | inf = self.prCyan("[INFO ]") 37 | if level == LOGLEVEL["ERROR"]: 38 | inf = self.prRed("[ERROR ]") 39 | if level == LOGLEVEL["WARNING"]: 40 | inf = self.prYello("[WARNING ]") 41 | if level == LOGLEVEL["LOG"]: 42 | inf = self.prGreen("[LOG ]") 43 | if level == LOGLEVEL["CRITICAL"]: 44 | inf = self.prPurple("[CRITICAL]") 45 | if level == LOGLEVEL["DEBUG"]: 46 | inf = self.prGray("[DEBUG ]") 47 | 48 | yl = self.prYello(f"[{str.ljust(scope, 20)}]") 49 | if(message == ""): 50 | print(f"[{self.getTimeSTR()}] {inf} {self.prYello("[global ]")} {scope}") 51 | else: 52 | print(f"[{self.getTimeSTR()}] {inf} {yl} {message}") 53 | 54 | def debug(self, scope: str, message = ""): 55 | self.print(scope, message, level=LOGLEVEL["DEBUG"]) 56 | def info(self, scope: str, message = ""): 57 | self.print(scope, message, level=LOGLEVEL["INFO"]) 58 | def warning(self, scope: str, message = ""): 59 | self.print(scope, message, level=LOGLEVEL["WARNING"]) 60 | def error(self, scope: str, message = ""): 61 | self.print(scope, message, level=LOGLEVEL["ERROR"]) 62 | def critical(self, scope: str, message = ""): 63 | self.print(scope, message, level=LOGLEVEL["CRITICAL"]) 64 | def log(self, scope: str, message = ""): 65 | self.print(scope, message, level=LOGLEVEL["LOG"]) 66 | 67 | def fit(self, stri: str, length: int): 68 | stri = str(stri) 69 | if(len(stri) <= length): 70 | return str.ljust(stri, length) 71 | else: 72 | strlen = len(stri) 73 | return "..." + stri[strlen - length + 3:] -------------------------------------------------------------------------------- /new_compiler.py: -------------------------------------------------------------------------------- 1 | from lark import Lark, Token 2 | from logger import L, LOGLEVEL 3 | import os 4 | import shutil 5 | from transform import DatapackGenerater, error_as_txt, modify_file_data, filedata 6 | from consts import planet_parser, NEW_LINE 7 | import datetime 8 | import sys 9 | import json 10 | 11 | 12 | logger = L() 13 | COMET_CACHE_FILE = "./comet_cache.txt" 14 | existing_functions = {} 15 | 16 | 17 | datapack_versions = { 18 | "1.20.4": "26", 19 | "1.20.6": "41", 20 | "1.21": "48", 21 | "1.21.1": "48", 22 | "1.21.2": "57", 23 | "1.21.3": "57", 24 | "1.21.4": "61", 25 | "1.21.5": "71" 26 | } 27 | 28 | def search_functions(function_folder_dir): 29 | global existing_functions 30 | if not os.path.exists(function_folder_dir): 31 | existing_functions = {} 32 | return 33 | filenames = os.listdir(function_folder_dir) 34 | for filename in filenames: 35 | if filename == "tick.mcfunction" or filename == "load.mcfunction": continue 36 | full_filename = os.path.join(function_folder_dir, filename) 37 | full_filename = full_filename.replace("\\", "/") 38 | if filename.split(".")[-1] != "mcfunction": search_functions(full_filename) 39 | else: existing_functions[full_filename] = True 40 | # 네임스페이스/functions, tick.json, load.json 삭제 후 재생성 41 | def make_basic_files(version, file_dir, namespace = "pack"): 42 | logger.debug("make_basic_files", f"version: {version}, file_dir: {file_dir}, namespace: {namespace}") 43 | 44 | function_folder = "function" 45 | if version[:4] == "1.20": function_folder = "functions" 46 | 47 | function_folder_dir = os.path.join(file_dir, namespace, "data", namespace, function_folder) 48 | tag_folder_dir = os.path.join(file_dir, namespace, "data", "minecraft", "tags", function_folder) 49 | 50 | 51 | # if os.path.exists(file_dir + f"{namespace}/data/{namespace}/{function_folder}"): shutil.rmtree(file_dir + f"{namespace}/data/{namespace}/{function_folder}") 52 | search_functions(function_folder_dir) 53 | if os.path.exists(function_folder_dir): shutil.rmtree(function_folder_dir) 54 | 55 | 56 | if not os.path.exists(tag_folder_dir): os.makedirs(tag_folder_dir) 57 | if not os.path.exists(function_folder_dir): os.makedirs(function_folder_dir) 58 | 59 | load_json = file_dir + f"{namespace}/data/minecraft/tags/{function_folder}/load.json" 60 | tick_json = file_dir + f"{namespace}/data/minecraft/tags/{function_folder}/tick.json" 61 | load_mcfunction = file_dir + f"{namespace}/data/{namespace}/{function_folder}/load.mcfunction" 62 | tick_mcfunction = file_dir + f"{namespace}/data/{namespace}/{function_folder}/tick.mcfunction" 63 | pack_mcmeta = file_dir + f"{namespace}/pack.mcmeta" 64 | file = open(load_json, "w+") 65 | file.write(f"{{\"values\": [\"{namespace}:load\"]}}") 66 | file.close() 67 | file = open(tick_json, "w+") 68 | file.write(f"{{\"values\": [\"{namespace}:tick\"]}}") 69 | file.close() 70 | if not os.path.isfile(load_mcfunction): 71 | file = open(load_mcfunction, "w+") 72 | file.write(f"\ 73 | # This data pack was compiled with the 40planet's compiler.\n\ 74 | # https://github.com/alexmonkey05/Datapack-Compiler\n\n") 75 | file.close() 76 | if not os.path.isfile(tick_mcfunction): 77 | file = open(tick_mcfunction, "w+") 78 | file.close() 79 | if not os.path.isfile(pack_mcmeta): 80 | file = open(pack_mcmeta, "w+") 81 | file.write('{ "pack": {"pack_format": ' + datapack_versions[version] + ', "description": "by 40planet"} }') 82 | file.close() 83 | 84 | 85 | def generate_datapack(filename, version, result_dir = "./", namespace = "pack"): 86 | # 파일 경로 가공 87 | result_dir = result_dir.strip() 88 | namespace = namespace.strip() 89 | if result_dir == "" or namespace == "": 90 | logger.critical("\n\nresult directory and namespace can not be empty string\n") 91 | return 92 | if result_dir[-1] != "/" and result_dir[-1] != "\\": 93 | result_dir += "/" 94 | 95 | # 데이터팩 기본 경로 만들기 96 | make_basic_files(version, result_dir, namespace) 97 | 98 | # 파일 경로 가공 99 | if len(filename) < 7 or filename[-7:] != ".planet": filename += ".planet" 100 | 101 | # .planet 파일 존재 확인 102 | if not os.path.isfile(filename): 103 | raise ValueError(error_as_txt(None, f"\"{filename}\" does not exist", filename, "", "fdsa")) 104 | 105 | 106 | # 파싱 107 | now = datetime.datetime.now() 108 | parser_tree = None 109 | with open(filename, "r", encoding="utf-8") as file: 110 | logger.debug("open_file", f"{logger.fit(filename, 20)} took {logger.prYello(int((datetime.datetime.now() - now).total_seconds() * 1000) / 1000)}s") 111 | 112 | now = datetime.datetime.now() 113 | file_data = modify_file_data(file.read()) 114 | 115 | parser_tree = planet_parser.parse(file_data + "\n") 116 | logger.debug("parse_file",f"{logger.fit(filename, 20)} took {logger.prYello(int((datetime.datetime.now() - now).total_seconds() * 1000) / 1000)}s") 117 | 118 | # make_basic_files("1.21", "./", "pack") 119 | 120 | # 트랜스폼 121 | now = datetime.datetime.now() 122 | # print(parser_tree.pretty()) 123 | datapack_generator = DatapackGenerater(version, result_dir, namespace, filename, logger_level=logger) 124 | datapack_generator.transform(parser_tree) 125 | logger.debug("interprete_file", f"{logger.fit(filename, 20)} took {logger.prYello(int((datetime.datetime.now() - now).total_seconds() * 1000) / 1000)}s") 126 | write_all_files() 127 | return parser_tree 128 | 129 | def write_all_files(): 130 | now = datetime.datetime.now() 131 | for filename in filedata: 132 | if filename in existing_functions: del existing_functions[filename] 133 | # if filename in comet_cache and filedata[filename] == comet_cache[filename]: continue 134 | with open(filename, "w+", encoding="utf-8") as file: 135 | file.write(filedata[filename]) 136 | # with open(COMET_CACHE_FILE, "w+", encoding="utf-8") as file: 137 | # file.write(str(filedata)) 138 | # for filename in existing_functions: 139 | # os.remove(filename) 140 | logger.debug("write_datapack", f"Took {logger.prYello(int((datetime.datetime.now() - now).total_seconds() * 1000) / 1000)}s") 141 | 142 | import argparse 143 | values = ["1.20.4", "1.20.6", "1.21", "1.21.1", "1.21.2", "1.21.3", "1.21.4", "1.21.5"] 144 | if __name__ == "__main__": 145 | 146 | # if os.path.isfile(COMET_CACHE_FILE): 147 | # with open(COMET_CACHE_FILE, "r+", encoding="utf-8") as file: 148 | # comet_cache = eval(file.read()) 149 | # else: 150 | # comet_cache = {} 151 | 152 | parser = argparse.ArgumentParser( 153 | prog='comet_compiler', 154 | description='Compile .planet files') 155 | parser.add_argument('--cli', action='store_true', help="Use cli instead of gui") # option that takes a value 156 | parser.add_argument('-p', '--planet', help="Select file to compile") 157 | parser.add_argument('-v', '--version', help="Select minecraft version") 158 | parser.add_argument('-d', '--dist', help="Select folder to locate output") 159 | parser.add_argument('-n', '--name', help="Input namespace. Default value is \"pack\".") 160 | parser.add_argument('-l', '--logger', help="Input logger level. Default value is \"INFO\".") 161 | args = parser.parse_args() 162 | if args.cli: 163 | logger.log("===============================================") 164 | logger.log(" ██████╗ ██████╗ ███╗ ███╗███████╗████████╗ ") 165 | logger.log(" ██╔════╝██╔═══██╗████╗ ████║██╔════╝╚══██╔══╝ ") 166 | logger.log(" ██║ ██║ ██║██╔████╔██║█████╗ ██║ ") 167 | logger.log(" ██║ ██║ ██║██║╚██╔╝██║██╔══╝ ██║ ") 168 | logger.log(" ╚██████╗╚██████╔╝██║ ╚═╝ ██║███████╗ ██║ ") 169 | logger.log(" ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ") 170 | logger.log("===============================================") 171 | 172 | now = datetime.datetime.now() 173 | 174 | v = args.version 175 | if v not in values or v == "": 176 | logger.critical(f"Invalid version: {v} / Required version: {values}") 177 | sys.exit(0) 178 | p = args.planet 179 | d = args.dist 180 | if p == None: 181 | logger.critical("planet file(-p / --planet) is required") 182 | sys.exit(0) 183 | if d == None: 184 | logger.critical("dist folder(-d / --dist) is required") 185 | sys.exit(0) 186 | n = args.name 187 | if n == None: 188 | n = "pack" 189 | logger.info("namespace", f"namespace is not defined, using default namespace: {logger.prGreen(n)}") 190 | l = args.logger 191 | if l == None: l = "INFO" 192 | logger.verboseLevel = LOGLEVEL[l] 193 | 194 | 195 | try: 196 | interprete_result = generate_datapack(p, v, d, n) 197 | except ValueError as err: 198 | print(err) 199 | sys.exit() 200 | logger.critical(err) 201 | took = int((datetime.datetime.now() - now).total_seconds() * 1000) / 1000 202 | logger.log(f"Done! Took {logger.prYello(took)}s") 203 | 204 | 205 | sys.exit(0) 206 | 207 | import eel 208 | import tkinter 209 | from tkinter import filedialog 210 | from eel import chrome, edge 211 | 212 | parentDir = os.path.dirname(__file__) 213 | 214 | eel.init(os.path.join(parentDir, "web")); 215 | 216 | @eel.expose 217 | def event(name, dir, version, namespace): 218 | try: 219 | generate_datapack(name, version, dir, namespace) 220 | return "success" 221 | except BaseException as error: 222 | logger.critical(str(error)); 223 | return str(error) 224 | 225 | 226 | @eel.expose 227 | def select_planet_file(): 228 | root = tkinter.Tk() 229 | root.attributes("-topmost", True) 230 | root.withdraw() 231 | result = filedialog.askopenfile( 232 | title="파일 선택창", 233 | filetypes=(('planet files', '*.planet'), ('all files', '*.*')) 234 | ) 235 | if result: 236 | return result.name 237 | else: 238 | return "" 239 | 240 | @eel.expose 241 | def select_folder(): 242 | root = tkinter.Tk() 243 | root.attributes("-topmost", True) 244 | root.withdraw() 245 | directory_path = filedialog.askdirectory() 246 | return directory_path 247 | 248 | 249 | import webbrowser 250 | @eel.expose 251 | def open_folder(path): 252 | webbrowser.open(f"file:///{path}") 253 | 254 | def __can_use_chrome(): 255 | """Identify if Chrome is available for Eel to use""" 256 | chrome_instance_path = chrome.find_path() 257 | return chrome_instance_path is not None and os.path.exists(chrome_instance_path) 258 | 259 | 260 | def __can_use_edge(): 261 | """Identify if Edge is available for Eel to use""" 262 | return edge.find_path() 263 | 264 | import socket 265 | 266 | def get_port(): 267 | """Get an available port by starting a new server, stopping and and returning the port""" 268 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 269 | sock.bind(("localhost", 0)) 270 | port = sock.getsockname()[1] 271 | sock.close() 272 | return port 273 | 274 | class UIOpenMode: 275 | NONE = 0 276 | CHROME_OR_EDGE = 1 277 | DEFAULT_BROWSER = 2 278 | 279 | # try: 280 | chrome_available = __can_use_chrome() 281 | edge_available = __can_use_edge() 282 | open_mode = UIOpenMode.CHROME_OR_EDGE 283 | 284 | if open_mode == UIOpenMode.CHROME_OR_EDGE and chrome_available: 285 | logger.info("The interface is being opened in a new Chrome window") 286 | logger.info( 287 | "Please do not close this terminal while using this compiler - the process will end when the window is closed" 288 | ) 289 | eel.start("index.html", size=(600, 800), port=0, mode="chrome") 290 | elif open_mode == UIOpenMode.CHROME_OR_EDGE and edge_available: 291 | logger.info("The interface is being opened in a new Edge window") 292 | logger.info( 293 | "Please do not close this terminal while using this compiler - the process will end when the window is closed" 294 | ) 295 | eel.start("index.html", size=(600, 800), port=0, mode="edge") 296 | elif open_mode == UIOpenMode.DEFAULT_BROWSER or ( 297 | open_mode == UIOpenMode.CHROME_OR_EDGE and not chrome_available and not edge_available 298 | ): 299 | logger.info("The interface is being opened in your default browser") 300 | logger.info( 301 | "Please do not close this terminal while using this compiler - the process will end when the window is closed" 302 | ) 303 | eel.start("index.html", size=(600, 800), port=0, mode="user default") 304 | else: 305 | port = get_port() 306 | logger.info(f"Server starting at http://localhost:{port}/index.html") 307 | logger.info("You may end this process using Ctrl+C when finished using auto-py-to-exe") 308 | eel.start("index.html", host="localhost", port=port, mode=None, close_callback=lambda x, y: None) -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Eel==0.18.1 2 | lark==1.2.2 3 | -------------------------------------------------------------------------------- /rpg_planet/blocks.planet: -------------------------------------------------------------------------------- 1 | /scoreboard objectives add 40planet_rpg_success_per dummy 2 | /scoreboard objectives add 40planet_rpg_fail_per dummy 3 | /scoreboard objectives add 40planet_rpg_destroy_per dummy 4 | /scoreboard players set 10 40planet_num 10 5 | 6 | var reinforce_cnt; 7 | var success_per = [ 8 | [100.0, 0.0, 0.0], # 0 9 | [90.0, 10.0, 0.0], # 1 10 | [85.0, 15.0, 0.0], # 2 11 | [85.0, 15.0, 0.0], # 3 12 | [80.0, 20.0, 0.0], # 4 13 | [75.0, 25.0, 0.0], # 5 14 | [70.0, 30.0, 0.0], # 6 15 | [65.0, 35.0, 0.0], # 7 16 | [60.0, 40.0, 0.0], # 8 17 | [55.0, 45.0, 0.0], # 9 18 | [50.0, 50.0, 0.0], # 10 19 | [45.0, 55.0, 0.0], # 11 20 | [40.0, 60.0, 0.0], # 12 21 | [35.0, 65.0, 0.0], # 13 22 | [30.0, 70.0, 0.0], # 14 23 | [30.0, 67.9, 2.1], # 15 24 | [30.0, 67.9, 2.1], # 16 25 | [30.0, 67.9, 2.1], # 17 26 | [30.0, 67.2, 2.8], # 18 27 | [30.0, 67.2, 2.8], # 19 28 | [30.0, 63.0, 7.0], # 20 29 | [30.0, 63.0, 7.0], # 21 30 | [3.0, 77.6, 19.4], # 22 31 | [2.0, 68.6, 29.4], # 23 32 | [1.0, 59.6, 39.4], # 24 33 | [-1.0, -1.0, -1.0], # 25 34 | ] 35 | 36 | def tick(){ 37 | /execute unless entity @e[tag=reinforce_table] run scoreboard players set $reinforce_table_id 40planet_id 0 38 | execute(as @e[tag=40planet_rpg_entity]){ 39 | execute (if entity @s[tag=summon_reinforce_table] at @s align xyz positioned "~.5 ~1 ~.5"){ 40 | /kill @s 41 | /setblock ~ ~-.1 ~ minecraft:blackstone 42 | /scoreboard players add $reinforce_table_id 40planet_id 1 43 | /summon item_display ~ ~ ~ {Passengers:[{alignment:"left",background:0,id:"minecraft:text_display",shadow:1b,text:'""',transformation:{left_rotation:[0f,1f,0f,0f],right_rotation:[0f,0f,0f,1f],scale:[1f,1f,1f],translation:[0f,0.1775f,0.375f]}},{alignment:"left",background:0,id:"minecraft:text_display",shadow:1b,text:'""',transformation:{left_rotation:[0f,1f,0f,0f],right_rotation:[0f,0f,0f,1f],scale:[1f,1f,1f],translation:[0f,0.1775f,0.375f]},Rotation:[180f,0f]}],Tags:["reinforce_table","40planet_rpg_entity","unset"],item:{components:{"minecraft:enchantments":{levels:{"minecraft:sharpness":1}}},count:1,id:"minecraft:smithing_table"},transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],scale:[1.01f,1.01f,1.01f],translation:[0f,-0.5f,0f]}} 44 | /summon item_display ~ ~.01 ~-.1875 {Tags:["unset","40planet_rpg_entity","reinforce_table_slot","reinforce_table_weapon"],Passengers:[{id:"interaction",response:1b,height:.1,width:.3}],item:{count:1,id:"minecraft:structure_void",components:{"minecraft:custom_data":{40planet_ui:1b}}},transformation:{left_rotation:[0.7071068f,0f,0f,0.7071068f],right_rotation:[0f,0f,0f,1f],scale:[0.31250003f,0.3125001f,0.43750042f],translation:[0f,0f,0f]}} 45 | /summon item_display ~-.25 ~.01 ~.1875 {Tags:["unset","40planet_rpg_entity","reinforce_table_slot"],Passengers:[{id:"interaction",response:1b,height:.1,width:.3}],item:{count:1,id:"minecraft:structure_void",components:{"minecraft:custom_data":{40planet_ui:1b}}},transformation:{left_rotation:[0.7071068f,0f,0f,0.7071068f],right_rotation:[0f,0f,0f,1f],scale:[0.31250003f,0.3125001f,0.43750042f],translation:[0f,0f,0f]}} 46 | /summon item_display ~.25 ~.01 ~.1875 {Tags:["unset","40planet_rpg_entity","reinforce_table_slot"],Passengers:[{id:"interaction",response:1b,height:.1,width:.3}],item:{count:1,id:"minecraft:structure_void",components:{"minecraft:custom_data":{40planet_ui:1b}}},transformation:{left_rotation:[0.7071068f,0f,0f,0.7071068f],right_rotation:[0f,0f,0f,1f],scale:[0.31250003f,0.3125001f,0.43750042f],translation:[0f,0f,0f]}} 47 | execute(as @e[distance=..0.5,tag=unset]){ 48 | /scoreboard players operation @s 40planet_id = $reinforce_table_id 40planet_id 49 | /tag @s remove unset 50 | } 51 | /playsound minecraft:block.stone.place block @a ~ ~ ~ 52 | } 53 | /execute if entity @s[tag=reinforce_table] at @s run function __namespace__:reinforce_table 54 | execute(if entity @s[tag=reinforce_text] at @s){ 55 | /tp @s ~ ~.05 ~ 56 | /scoreboard players add @s 40planet_num 1 57 | /execute if score @s 40planet_num matches 10 run kill @s 58 | } 59 | } 60 | execute(as @e[tag=,type=item]){ 61 | /tag @s add at_e 62 | /data modify entity @s CustomName set from entity @s Item.components."minecraft:custom_name" 63 | /data modify entity @s CustomNameVisible set value 1b 64 | } 65 | } 66 | 67 | var target_attack 68 | def return_item(){ 69 | /execute in minecraft:overworld run item replace block 15 -60 15 container.1 from entity @s container.0 70 | /execute on passengers on ^target_attack& at @s run summon item ~ ~1.5 ~ {PickupDelay:0s,Item:{id:"stone",count:1b},Tags:["40planet_rpg_item"]} 71 | /execute unless items entity @s container.0 *[minecraft:custom_data~{40planet_ui:1b}] on passengers unless data entity @s attack unless data entity @s interaction at @s run summon item ~ ~ ~ {PickupDelay:0s,Item:{id:"stone",count:1b},Tags:["40planet_rpg_item"]} 72 | /item replace entity @s container.0 with minecraft:structure_void[minecraft:custom_data={40planet_ui:1b}] 73 | execute(as @n[tag=40planet_rpg_item]){ 74 | /execute in minecraft:overworld run item replace entity @s container.0 from block 15 -60 15 container.1 75 | /tag @s remove 40planet_rpg_item 76 | } 77 | } 78 | 79 | def update_text(){ 80 | 81 | 82 | /scoreboard players operation temp 40planet_num = @s 40planet_id 83 | execute(as @e[distance=..0.5,tag=reinforce_table_slot] if score "@s" "40planet_id" = "temp" "40planet_num"){ 84 | /execute if items entity @s container.0 *[custom_data~{40planet_ui:1b}] run return 0 85 | execute(if entity @s[tag=reinforce_table_weapon]){ 86 | execute(if data entity "@s" 'item.components."minecraft:custom_data".percent'){ 87 | /execute store result score success 40planet_num run data get entity @s item.components."minecraft:custom_data".percent[0] 10 88 | /execute store result score fail 40planet_num run data get entity @s item.components."minecraft:custom_data".percent[1] 10 89 | /execute store result score destroy 40planet_num run data get entity @s item.components."minecraft:custom_data".percent[2] 10 90 | } 91 | execute(unless data entity "@s" 'item.components."minecraft:custom_data".percent'){ 92 | /data modify entity @s item.components."minecraft:custom_data".percent set value [100.0, .0, .0] 93 | /scoreboard players set success 40planet_num 1000 94 | /scoreboard players set fail 40planet_num 0 95 | /scoreboard players set destroy 40planet_num 0 96 | } 97 | } 98 | execute(unless entity @s[tag=reinforce_table_weapon] if items entity @s container.0 *[custom_data~{40planet_rpg_stone:1b}]){ 99 | /execute store result score temp 40planet_num run data get entity @s item.components."minecraft:custom_data".percent 10 100 | /scoreboard players operation success 40planet_num += temp 40planet_num 101 | /scoreboard players operation fail 40planet_num -= temp 40planet_num 102 | execute(if score "fail" "40planet_num" matches ..-1){ 103 | /scoreboard players operation destroy 40planet_num += fail 40planet_num 104 | /scoreboard players set fail 40planet_num 0 105 | /execute if score destroy 40planet_num matches ..-1 run scoreboard players set destroy 40planet_num 0 106 | } 107 | } 108 | } 109 | 110 | execute (if score "success" "40planet_num" matches 0 if score "fail" "40planet_num" matches 0 if score "destroy" "40planet_num" matches 0){ 111 | /execute on passengers run data modify entity @s text set value '""' 112 | return 0 113 | } 114 | 115 | /scoreboard players operation @s 40planet_rpg_success_per = success 40planet_num 116 | /scoreboard players operation @s 40planet_rpg_fail_per = fail 40planet_num 117 | /scoreboard players operation @s 40planet_rpg_destroy_per = destroy 40planet_num 118 | 119 | /scoreboard players operation success_ 40planet_num = success 40planet_num 120 | /scoreboard players operation fail_ 40planet_num = fail 40planet_num 121 | /scoreboard players operation destroy_ 40planet_num = destroy 40planet_num 122 | 123 | /scoreboard players operation success 40planet_num /= 10 40planet_num 124 | /scoreboard players operation fail 40planet_num /= 10 40planet_num 125 | /scoreboard players operation destroy 40planet_num /= 10 40planet_num 126 | /scoreboard players operation success_ 40planet_num %= 10 40planet_num 127 | /scoreboard players operation fail_ 40planet_num %= 10 40planet_num 128 | /scoreboard players operation destroy_ 40planet_num %= 10 40planet_num 129 | 130 | 131 | /execute on passengers run data modify entity @s text set value '["",{"text":"성공: ","color":"green"},{"score":{"name":"success","objective":"40planet_num"}},".",{"score":{"name":"success_","objective":"40planet_num"}},{"text":"\\n실패: ","color":"red"},{"score":{"name":"fail","objective":"40planet_num"}},".",{"score":{"name":"fail_","objective":"40planet_num"}},{"text":"\\n파괴: ","color":"dark_red"},{"score":{"name":"destroy","objective":"40planet_num"}},".",{"score":{"name":"destroy_","objective":"40planet_num"}}]' 132 | } 133 | 134 | # 강화석, 스크롤 지우기 135 | def remove_items(){ 136 | /data modify storage 40planet:rpg scrolls set value [] 137 | execute(as @e[distance=..0.5,tag=reinforce_table_slot,tag=!reinforce_table_weapon] if score "@s" "40planet_id" = "temp" "40planet_num"){ 138 | # 스크롤 정보 저장 139 | execute(if items entity @s container.0 *[custom_data~{40planet_rpg_scroll:1b}]){ 140 | /data modify storage 40planet:rpg scrolls append from entity @s item.components."minecraft:custom_data" 141 | } 142 | /item replace entity @s container.0 with minecraft:structure_void[minecraft:custom_data={40planet_ui:1b}] 143 | } 144 | } 145 | 146 | 147 | def upgrade(var type, var value){ 148 | /execute unless data entity @s item.components."minecraft:custom_data".upgrade run data modify entity @s item.components."minecraft:custom_data".upgrade set value [{type:"health",value:0},{type:"strength",value:0},{type:"speed",value:0},{type:"mana",value:0}] 149 | /execute store result score value 40planet_num run data get entity @s item.components."minecraft:custom_data".upgrade[{type:"^type&"}].value 150 | /execute store result entity @s item.components."minecraft:custom_data".upgrade[{type:"^type&"}].value int 1 run scoreboard players add value 40planet_num ^value& 151 | 152 | while(true){ 153 | /data remove storage 40planet:rpg temp 154 | /data modify storage 40planet:rpg temp.lore set string entity @s item.components."minecraft:lore"[-1] 1 32 155 | /execute unless data storage 40planet:rpg temp{lore:"\"color\":\"yellow\",\"italic\":false"} run return 0 156 | /data remove entity @s item.components."minecraft:lore"[-1] 157 | } 158 | var health = get_data("entity", "@s", "item.components.'minecraft:custom_data'.upgrade[0].value") 159 | var strength = get_data("entity", "@s", "item.components.'minecraft:custom_data'.upgrade[1].value") 160 | var speed = get_data("entity", "@s", "item.components.'minecraft:custom_data'.upgrade[2].value") 161 | var mana = get_data("entity", "@s", "item.components.'minecraft:custom_data'.upgrade[3].value") 162 | var reinforce_cnt = get_data("entity", "@s", "item.components.'minecraft:custom_data'.reinforce_cnt") 163 | /scoreboard players set temp 40planet_num 0 164 | /execute unless data entity @s item.components."minecraft:lore" run scoreboard players set temp 40planet_num 1 165 | /execute if score temp 40planet_num matches 1 run data modify entity @s item.components."minecraft:lore" set value ["{\"color\":\"yellow\",\"italic\":false,\"text\":\"+^reinforce_cnt&강\"}","{\"color\":\"yellow\",\"italic\":false,\"text\":\"체력 ^health&\"}","{\"color\":\"yellow\",\"italic\":false,\"text\":\"근력 ^strength&\"}","{\"color\":\"yellow\",\"italic\":false,\"text\":\"민첩 ^speed&\"}","{\"color\":\"yellow\",\"italic\":false,\"text\":\"마나 ^mana&\"}"] 166 | execute(if score "temp" "40planet_num" matches 0){ 167 | /data modify entity @s item.components."minecraft:lore" append value "{\"color\":\"yellow\",\"italic\":false,\"text\":\"+^reinforce_cnt&강\"}" 168 | /data modify entity @s item.components."minecraft:lore" append value "{\"color\":\"yellow\",\"italic\":false,\"text\":\"체력 ^health&\"}" 169 | /data modify entity @s item.components."minecraft:lore" append value "{\"color\":\"yellow\",\"italic\":false,\"text\":\"근력 ^strength&\"}" 170 | /data modify entity @s item.components."minecraft:lore" append value "{\"color\":\"yellow\",\"italic\":false,\"text\":\"민첩 ^speed&\"}" 171 | /data modify entity @s item.components."minecraft:lore" append value "{\"color\":\"yellow\",\"italic\":false,\"text\":\"마나 ^mana&\"}" 172 | } 173 | } 174 | 175 | def success(){ 176 | /execute at @s run playsound minecraft:block.anvil.use block @a ~ ~ ~ 1 1 177 | /execute at @s run particle minecraft:happy_villager ~ ~ ~ .5 .3 .5 2 20 178 | reinforce_cnt = reinforce_cnt + 1 179 | /execute align xz run summon text_display ~.5 ~.3 ~.5 {text:'{"text":"+^reinforce_cnt&강","color":"green"}',background:0,shadow:1b,billboard:"vertical",Tags:["reinforce_text","40planet_rpg_entity"]} 180 | set_data("entity", "@s", "item.components.'minecraft:custom_data'.percent", success_per[reinforce_cnt]) 181 | set_data("entity", "@s", "item.components.'minecraft:custom_data'.reinforce_cnt", reinforce_cnt) 182 | /execute at @s as @n[tag=reinforce_table] run function __namespace__:update_text 183 | 184 | # 장비별 스텟 추가 185 | execute(if data entity "@s" "item.components.'minecraft:custom_data'.40planet_equipment"){ 186 | # 공격력 추가 187 | /scoreboard players set temp 40planet_num 0 188 | /execute if data entity @s item.components.'minecraft:attribute_modifiers'.modifiers run scoreboard players set temp 40planet_num 1 189 | /execute if data entity @s item.components.'minecraft:attribute_modifiers'.modifiers[{type:'minecraft:generic.attack_damage'}] run scoreboard players set temp 40planet_num 2 190 | /execute if score temp 40planet_num matches 1 run data modify entity @s item.components.'minecraft:attribute_modifiers'.modifiers append value {type:"generic.attack_damage",amount:1,slot:mainhand,operation:add_value,id:1524155694201} 191 | /execute if score temp 40planet_num matches 0 run data modify entity @s item.components.'minecraft:attribute_modifiers'.modifiers set value [{type:"generic.attack_damage",amount:1,slot:mainhand,operation:add_value,id:1524155694201}] 192 | execute(if score "temp" "40planet_num" matches 2){ 193 | /execute store result score value 40planet_num run data get entity @s item.components.'minecraft:attribute_modifiers'.modifiers[{type:'minecraft:generic.attack_damage'}].amount 10 194 | /execute store result entity @s item.components.'minecraft:attribute_modifiers'.modifiers[{type:'minecraft:generic.attack_damage'}].amount double 0.1 run scoreboard players add value 40planet_num 10 195 | } 196 | 197 | # lore 설정 198 | while(true){ 199 | /data remove storage 40planet:rpg temp 200 | /data modify storage 40planet:rpg temp.lore set string entity @s item.components."minecraft:lore"[0] 1 32 201 | /execute unless data storage 40planet:rpg temp{lore:"\"color\":\"yellow\",\"italic\":false"} run return 0 202 | /data remove entity @s item.components."minecraft:lore"[0] 203 | } 204 | /scoreboard players set temp 40planet_num 0 205 | /execute unless data entity @s item.components."minecraft:lore" run scoreboard players set temp 40planet_num 1 206 | /execute if score temp 40planet_num matches 1 run data modify entity @s item.components."minecraft:lore" set value ["{\"color\":\"yellow\",\"italic\":false,\"text\":\"+^reinforce_cnt&강\"}"] 207 | /execute if score temp 40planet_num matches 0 run data modify entity @s item.components."minecraft:lore" prepend value "{\"color\":\"yellow\",\"italic\":false,\"text\":\"+^reinforce_cnt&강\"}" 208 | } 209 | set_score("type", "40planet_num", 0) 210 | /execute if data entity @s item.components.'minecraft:custom_data'.40planet_helmet run scoreboard players set type 40planet_num 1 211 | /execute if data entity @s item.components.'minecraft:custom_data'.40planet_chestplate run scoreboard players set type 40planet_num 2 212 | execute(if score "type" "40planet_num" matches 1..2){ 213 | upgrade("health", 1) 214 | } 215 | execute(if data entity "@s" "item.components.'minecraft:custom_data'.40planet_leggings"){ 216 | upgrade("strength", 1) 217 | } 218 | execute(if data entity "@s" "item.components.'minecraft:custom_data'.40planet_boots"){ 219 | upgrade("speed", 1) 220 | } 221 | execute(if data entity "@s" "item.components.'minecraft:custom_data'.40planet_ring"){ 222 | upgrade("mana", 1) 223 | } 224 | 225 | var scrolls = get_data("storage", "40planet:rpg", "scrolls") 226 | # print(scrolls) 227 | var scrolls_len = len(scrolls) 228 | var i = 0; 229 | while(i < scrolls_len){ 230 | execute(if data entity "@s" "item.components.'minecraft:custom_data'.40planet_neck"){ 231 | upgrade(scrolls[0].type, int(double(scrolls[0].value) * 1.5)) 232 | } 233 | execute(unless data entity "@s" "item.components.'minecraft:custom_data'.40planet_neck"){ 234 | upgrade(scrolls[0].type, scrolls[0].value) 235 | } 236 | del(scrolls[0]) 237 | i = i + 1; 238 | } 239 | } 240 | 241 | def fail(){ 242 | execute(at @s align xz positioned "~.5 ~ ~.5"){ 243 | /execute as @n[tag=reinforce_table] run function __namespace__:update_text 244 | /playsound minecraft:block.anvil.destroy block @a ~ ~ ~ 1 1 245 | /particle minecraft:angry_villager ~ ~ ~ .3 .1 .3 1 7 246 | } 247 | } 248 | 249 | def destroy(){ 250 | execute(at @s align xz positioned "~.5 ~ ~.5"){ 251 | /playsound minecraft:entity.generic.explode block @a ~ ~ ~ 252 | /particle minecraft:explosion ~ ~ ~ .1 .1 .1 2 5 253 | } 254 | /item replace entity @s container.0 with minecraft:structure_void[minecraft:custom_data={40planet_ui:1b}] 255 | /execute at @s as @n[tag=reinforce_table] run function __namespace__:update_text 256 | } 257 | 258 | def reinforce(){ 259 | 260 | /data modify storage 40planet:rpg selected_item set from entity @s item 261 | reinforce_cnt = get_data("storage", "40planet:rpg", "selected_item.components.'minecraft:custom_data'.reinforce_cnt") 262 | execute(unless data storage "40planet:rpg" "selected_item.components.'minecraft:custom_data'.reinforce_cnt"){ 263 | reinforce_cnt = 0 264 | } 265 | 266 | set_score("require_level", "40planet_num", reinforce_cnt) 267 | execute(if score "require_level" "40planet_num" matches 25 on passengers){ 268 | /execute on target run tellraw @s [{"text":"더 이상 강화할 수 없습니다.","color":"red"}] 269 | /execute on target run playsound minecraft:block.note_block.bass weather @s ~ ~ ~ 270 | return 0 271 | } 272 | /execute store result score temp 40planet_num on passengers on target if score require_level 40planet_num <= @s 40planet_level 273 | execute(if score "temp" "40planet_num" matches 0 on passengers){ 274 | /execute on target run tellraw @s [{"text":"레벨이 부족합니다. 요구 레벨: ","color":"red"},{"score":{"name":"require_level","objective":"40planet_num"}}] 275 | /execute on target run playsound minecraft:block.note_block.bass weather @s ~ ~ ~ 276 | return 0 277 | } 278 | 279 | /execute on passengers on target run xp add @s -^reinforce_cnt& levels 280 | /scoreboard players operation temp 40planet_num = @s 40planet_id 281 | remove_items() 282 | 283 | # 확률 가져오기 284 | execute(at @s as @n[tag=reinforce_table]){ 285 | /scoreboard players operation success 40planet_num = @s 40planet_rpg_success_per 286 | /scoreboard players operation fail 40planet_num = @s 40planet_rpg_fail_per 287 | /scoreboard players operation destroy 40planet_num = @s 40planet_rpg_destroy_per 288 | } 289 | 290 | /execute store result score result 40planet_num run random value 1..1000 291 | 292 | # 성공 293 | execute(if score "result" "40planet_num" <= "success" "40planet_num"){ 294 | success() 295 | return 0 296 | } 297 | /scoreboard players operation result 40planet_num -= success 40planet_num 298 | 299 | # 실패 300 | execute(if score "result" "40planet_num" <= "fail" "40planet_num"){ 301 | fail() 302 | return 0 303 | } 304 | 305 | # 파괴 306 | destroy() 307 | } 308 | 309 | # 강화 작업대 (스크롤 & 강화석으로 장비 강화) 310 | def reinforce_table(){ 311 | /scoreboard players operation temp 40planet_num = @s 40planet_id 312 | execute(if block "~ ~-.1 ~" air){ 313 | /execute positioned ~ ~-.5 ~ as @e[distance=..0.5] if items entity @s container.0 blackstone run data modify entity @s Item set value {components:{"minecraft:entity_data":{id:"marker",Tags:["40planet_rpg_entity","summon_reinforce_table"]},"minecraft:custom_name":'{"italic":false,"text":"강화 작업대"}'},id:"ender_dragon_spawn_egg"} 314 | /execute on passengers run kill @s 315 | /kill @s 316 | execute(as @e[distance=..0.5,tag=reinforce_table_slot] if score "@s" "40planet_id" = "temp" "40planet_num"){ 317 | return_item() 318 | /execute on passengers run kill @s 319 | /kill @s 320 | } 321 | return 0 322 | } 323 | /scoreboard players reset is_weapon_update 40planet_num 324 | /scoreboard players set success 40planet_num 0 325 | /scoreboard players set fail 40planet_num 0 326 | /scoreboard players set destroy 40planet_num 0 327 | execute(as @e[distance=..0.5,tag=reinforce_table_slot] if score "@s" "40planet_id" = "temp" "40planet_num"){ 328 | # 아이템 넣기 329 | /scoreboard players set temp 40planet_num 0 330 | /execute on passengers on target run scoreboard players set temp 40planet_num 1 331 | execute(if score "temp" "40planet_num" matches 1){ 332 | 333 | # target이 웅크리고 있다면 강화하기 함수 실행하는 코드 334 | execute(if entity @s[tag=reinforce_table_weapon]){ 335 | /execute on passengers on target unless predicate rpg:sneaking run return 0 336 | /execute if items entity @s container.0 *[custom_data~{40planet_ui:1b}] run return 0 337 | 338 | reinforce() 339 | 340 | /execute on passengers run data remove entity @s interaction 341 | return 0 342 | } 343 | 344 | /execute on passengers on target run data modify storage 40planet:rpg selected_item set from entity @s SelectedItem 345 | /scoreboard players set temp 40planet_num 0 346 | execute(if entity @s[tag=reinforce_table_weapon]){ # 무기 슬롯인 경우 347 | /execute if data storage 40planet:rpg selected_item.components."minecraft:custom_data".40planet_armor run scoreboard players set temp 40planet_num 1 348 | /execute if data storage 40planet:rpg selected_item.components."minecraft:custom_data".40planet_equipment run scoreboard players set temp 40planet_num 1 349 | } 350 | execute(unless entity @s[tag=reinforce_table_weapon]){ # 강화석, 스크롤 슬롯인 경우 351 | /execute if data storage 40planet:rpg selected_item.components."minecraft:custom_data".40planet_rpg_stone run scoreboard players set temp 40planet_num 1 352 | /execute if data storage 40planet:rpg selected_item.components."minecraft:custom_data".40planet_rpg_scroll run scoreboard players set temp 40planet_num 1 353 | } 354 | /execute on passengers on target unless data entity @s SelectedItem run scoreboard players set temp 40planet_num 0 355 | 356 | execute(if score "temp" "40planet_num" matches 1){ 357 | /execute on passengers on target run item modify entity @s weapon rpg:weapon_minus 358 | # 이미 다른 아이템이 있으면 돌려주기 359 | target_attack = "target" 360 | /execute unless items entity @s container.0 *[minecraft:custom_data~{40planet_ui:1b}] run function __namespace__:return_item 361 | 362 | /data modify storage 40planet:rpg selected_item.count set value 1 363 | /data modify entity @s item set from storage 40planet:rpg selected_item 364 | 365 | /scoreboard players set is_weapon_update 40planet_num 1 366 | } 367 | 368 | 369 | /execute on passengers run data remove entity @s interaction 370 | } 371 | 372 | # 아이템 빼기 373 | /scoreboard players set temp 40planet_num 0 374 | /execute on passengers on attacker run scoreboard players set temp 40planet_num 1 375 | /execute if items entity @s container.0 *[custom_data~{40planet_ui:1b}] run scoreboard players set temp 40planet_num 0 376 | execute(if score "temp" "40planet_num" matches 1){ 377 | target_attack = "attacker" 378 | return_item() 379 | /execute on passengers run data remove entity @s attack 380 | 381 | /scoreboard players set is_weapon_update 40planet_num 1 382 | } 383 | } 384 | 385 | # 무기 슬롯에 변화가 없었다면 종료 386 | /execute unless score is_weapon_update 40planet_num = is_weapon_update 40planet_num run return 0 387 | update_text() 388 | } -------------------------------------------------------------------------------- /rpg_planet/camera.planet: -------------------------------------------------------------------------------- 1 | 2 | var camera_paths 3 | var selected_path 4 | /scoreboard players set rot_x 40planet_camera_num 200 5 | /scoreboard players set rot_y 40planet_camera_num 200 6 | 7 | def get_wand(){ 8 | /give @p minecraft:stick[minecraft:custom_data={40planet_wand:1b},minecraft:food={nutrition:0,saturation:0,can_always_eat:true,eat_seconds:2147483647}] 9 | } 10 | 11 | def first_load(){ 12 | /scoreboard objectives add 40planet_camera_num dummy 13 | /scoreboard objectives add 40planet_camera_timer dummy 14 | /scoreboard objectives add 40planet_camera_is_playing dummy 15 | /scoreboard objectives add 40planet_camera_point_num dummy 16 | /scoreboard objectives add 40planet_id dummy 17 | camera_paths = [] 18 | /scoreboard players set is_selected 40planet_camera_num 0 19 | /execute as @a store result score @s 40planet_id run scoreboard players add #first 40planet_id 1 20 | /scoreboard objectives add 40planet_camera_stick_drop minecraft.dropped:minecraft.stick 21 | /scoreboard players set rot_x 40planet_camera_num 200 22 | /scoreboard players set rot_y 40planet_camera_num 200 23 | selected_path = 0 24 | } 25 | 26 | def play(var idx){ 27 | var camera_path = camera_paths[idx] 28 | /scoreboard players set @s 40planet_camera_is_playing 1 29 | /scoreboard players set @s 40planet_camera_point_num 0 30 | set_score("@s", "40planet_camera_timer", camera_path[0][3]) 31 | } 32 | 33 | def add_path(){ append(camera_paths, []) } 34 | def remove_path(var num){ del(camera_paths[num]) } 35 | def add_point(var x, var y, var z, var r1, var r2, var t){ append(camera_paths[selected_path], [x, y, z, r1, r2, t]) } 36 | def remove_point(var num, var num2){ del(camera_paths[num][num2]) } 37 | 38 | def summon_point(){ 39 | execute( positioned ~ ~1.5 ~ summon item_display){ 40 | /data merge entity @s {item:{id:"dropper",Count:1b},Tags:["40planet_camera_marker"]} 41 | var point_idx = len(camera_paths[selected_path]) 42 | print(point_idx) 43 | set_data("entity", "@s", "item.components.minecraft:custom_data.point_idx", point_idx) 44 | } 45 | add_point(get_data("entity", "@s", "Pos[0]"), get_data("entity", "@s", "Pos[1]") + 1.5, get_data("entity", "@s", "Pos[2]"), get_data("entity", "@s", "Rotation[0]"), get_data("entity", "@s", "Rotation[1]"), 20) 46 | } 47 | 48 | def next_point(){ 49 | /scoreboard players add @s 40planet_camera_point_num 1 50 | var point_idx = get_score("@s", "40planet_camera_point_num") 51 | var path_idx = get_score("@s", "40planet_camera_num") 52 | execute(unless data camera_paths[path_idx][point_idx]){ 53 | /scoreboard players set @s 40planet_camera_is_playing 0 54 | return 0 55 | } 56 | var point = camera_paths[path_idx][point_idx] 57 | print(point) 58 | } 59 | 60 | 61 | def unselect_all(){ 62 | execute(as @e[tag=40planet_camera_selected_marker]){ 63 | /tag @s remove 40planet_camera_selected_marker 64 | /data modify entity @s Glowing set value 0 65 | } 66 | /scoreboard players set is_selected 40planet_camera_num 0 67 | } 68 | 69 | 70 | def tick_player(){ 71 | execute(if score "@s" "40planet_camera_is_playing" matches 1){ # 재생 중인 플레이어라면 72 | /scoreboard players remove @s 40planet_camera_timer 1 73 | /execute if score @s 40planet_camera_timer matches ..0 run function __namespace__:next_point 74 | } 75 | 76 | execute(if items entity @s weapon.mainhand minecraft:stick[minecraft:custom_data={40planet_wand:1b}]){ 77 | execute( unless entity @s[tag=40planet_click_wand] ) { 78 | /scoreboard players set rot_x 40planet_camera_num 200 79 | } 80 | /execute if entity @s[tag=40planet_click_wand] run tag @s remove 40planet_click_wand 81 | } 82 | 83 | execute(if items entity @s weapon.offhand minecraft:stick[minecraft:custom_data={40planet_wand:1b}]){ 84 | /item replace entity @s weapon.mainhand from entity @s weapon.offhand 85 | /item replace entity @s weapon.offhand with air 86 | execute(as @e[tag=40planet_camera_selected_marker]){ 87 | var point_idx = get_data("entity", "@s", "item.components.minecraft:custom_data.point_idx") 88 | #print(point_idx) 89 | del(camera_paths[selected_path][point_idx]) 90 | /kill @s 91 | /scoreboard players set is_selected 40planet_camera_num 0 92 | } 93 | } 94 | 95 | execute(if score "@s" "40planet_camera_stick_drop" matches 1..){ 96 | execute(as @e[tag=40planet_camera_selected_marker]){ 97 | var point_idx = get_data("entity", "@s", "item.components.minecraft:custom_data.point_idx") 98 | var rotation = get_data("entity", "@s", "Rotation") 99 | camera_paths[selected_path][point_idx][3] = rotation[0] 100 | camera_paths[selected_path][point_idx][4] = rotation[1] 101 | 102 | } 103 | unselect_all() 104 | get_wand() 105 | /kill @e[type=item,nbt={Item:{components:{"minecraft:custom_data":{40planet_wand:1b}}}}] 106 | /scoreboard players set @s 40planet_camera_stick_drop 0 107 | } 108 | } 109 | 110 | /advancement revoke @s only __namespace__:using_wand 111 | def click_wand(){ 112 | /advancement revoke @s only __namespace__:using_wand 113 | /execute unless items entity @s weapon.mainhand minecraft:stick[minecraft:custom_data={40planet_wand:1b}] run return 0 114 | /tag @s add 40planet_click_wand 115 | execute( if score "is_selected" "40planet_camera_num" matches 0 ){ # 바라보고 있는 마커 선택 116 | unselect_all() 117 | /scoreboard players set #temp 40planet_camera_num 0 118 | /tag @s add this 119 | execute( as @e[tag=40planet_camera_marker] positioned as @s facing entity @p[tag=this] feet positioned ^ ^ ^1 rotated as @p[tag=this] positioned ^ ^ ^1 if entity @s[distance=..0.5] ){ 120 | /execute if score #temp 40planet_camera_num matches 1 run return 0 121 | /tag @s add 40planet_camera_selected_marker 122 | /data modify entity @s Glowing set value 1b 123 | /scoreboard players set is_selected 40planet_camera_num 1 124 | /scoreboard players set #temp 40planet_camera_num 1 125 | } 126 | /tag @s remove this 127 | return 0 128 | } 129 | /execute store result score player_x 40planet_camera_num run data get entity @s Rotation[0] 130 | /execute store result score player_y 40planet_camera_num run data get entity @s Rotation[1] 131 | execute( if score "rot_x" "40planet_camera_num" matches 200 ){ 132 | execute( as @e[tag=40planet_camera_selected_marker] ){ 133 | /execute store result score rot_x 40planet_camera_num run data get entity @s Rotation[0] 134 | /execute store result score rot_y 40planet_camera_num run data get entity @s Rotation[1] 135 | } 136 | /scoreboard players operation rot_x 40planet_camera_num -= player_x 40planet_camera_num 137 | /scoreboard players operation rot_y 40planet_camera_num -= player_y 40planet_camera_num 138 | } 139 | execute( as @e[tag=40planet_camera_selected_marker] ){ 140 | /execute store result entity @s Rotation[0] float 1 run scoreboard players operation player_x 40planet_camera_num += rot_x 40planet_camera_num 141 | /execute store result entity @s Rotation[1] float 1 run scoreboard players operation player_y 40planet_camera_num += rot_y 40planet_camera_num 142 | } 143 | } 144 | 145 | def tick(){ 146 | if( is_module() ){ return 0 } 147 | execute(as @a){ tick_player() } 148 | } 149 | 150 | 151 | 152 | 153 | if( !(is_module()) ){ 154 | /execute unless score #first 40planet_id = #first 40planet_id run function __namespace__:first_load 155 | } 156 | 157 | def test(){ 158 | /scoreboard players set @s 40planet_camera_num 1 159 | play(get_score("@s", "40planet_camera_num")) 160 | } -------------------------------------------------------------------------------- /rpg_planet/id.planet: -------------------------------------------------------------------------------- 1 | /scoreboard objectives add 40planet_id dummy 2 | 3 | def set_id(){ 4 | 5 | var uuid = get_data("entity", "@s", "UUID") 6 | /scoreboard players set is_uuid_exist 40planet_num 0 7 | /execute if data storage 40planet:id player."^uuid&".id run scoreboard players set is_uuid_exist 40planet_num 1 8 | # uuid가 있을 때 9 | /execute if score is_uuid_exist 40planet_num matches 1 store result score @s 40planet_id run data get storage 40planet:id player."^uuid&".id 10 | # uuid가 없을 때 11 | execute(if score "is_uuid_exist" "40planet_num" matches 0){ 12 | /execute store result score @s 40planet_id run scoreboard players add $first 40planet_id 1 13 | /execute store result storage 40planet:id player."^uuid&".id int 1 run scoreboard players get $first 40planet_id 14 | } 15 | return get_score("@s", "40planet_id") 16 | } 17 | 18 | def tick(){ 19 | /execute as @a unless score @s 40planet_id = @s 40planet_id run function __namespace__:set_id 20 | 21 | # if(is_module()){ return 0 } 22 | } 23 | 24 | def get_id(){ 25 | return get_score("@s", "40planet_id") 26 | } 27 | 28 | 29 | /execute unless score $first 40planet_id = $first 40planet_id run scoreboard players set $first 40planet_id -2147483647 -------------------------------------------------------------------------------- /rpg_planet/main_display.planet: -------------------------------------------------------------------------------- 1 | import id 2 | import skill 3 | import stat 4 | # import blocks 5 | 6 | 7 | /scoreboard objectives add 40planet_inv_idx dummy 8 | /scoreboard objectives add 40planet_rpg_first dummy 9 | /scoreboard objectives add 40planet_rpg_equipment_health dummy 10 | /scoreboard objectives add 40planet_rpg_equipment_strength dummy 11 | /scoreboard objectives add 40planet_rpg_equipment_speed dummy 12 | /scoreboard objectives add 40planet_rpg_equipment_mana dummy 13 | /scoreboard objectives add 40planet_rpg_leave minecraft.custom:minecraft.leave_game 14 | 15 | var inv_ui; 16 | var player_id; 17 | var inv_ui_len; 18 | 19 | 20 | def first_load_player(){ 21 | /scoreboard players set @s 40planet_inv_idx 0 22 | /scoreboard players set @s 40planet_rpg_first 0 23 | player_id = id.set_id() 24 | /data modify storage 40planet:rpg players.^player_id&.armor set value [{}, {}, {}, {}, {}, {}, {}] 25 | /item replace entity @s container.17 with command_block[minecraft:custom_data={40planet_inv_btn:1b,40planet_ui:1b},minecraft:custom_name='{"text":"메뉴","italic":false}'] 26 | } 27 | 28 | # slot번째 슬롯의 아이템 돌려주고 지우기 29 | def return_item(var slot){ 30 | /execute in minecraft:overworld run item replace block 15 -60 15 container.1 from entity @s container.^slot& 31 | /execute in minecraft:overworld unless items block 15 -60 15 container.1 * run return 0 32 | /item replace entity @s container.^slot& with air 33 | /execute at @s anchored eyes positioned ^ ^ ^ run summon item ~ ~ ~ {PickupDelay:0s,Item:{id:"stone",count:1b},Tags:["40planet_rpg_item"]} 34 | execute(as @e[tag=40planet_rpg_item,limit=1]){ 35 | /execute in minecraft:overworld run item replace entity @s container.0 from block 15 -60 15 container.1 36 | /tag @s remove 40planet_rpg_item 37 | } 38 | } 39 | 40 | def update_stat(){ # 장비 스텟 + 기본 스텟 적용하기 41 | /scoreboard players set @s 40planet_rpg_leave 0 42 | 43 | /scoreboard players operation @s 40planet_rpg_health += @s 40planet_rpg_equipment_health 44 | /scoreboard players operation @s 40planet_rpg_strength += @s 40planet_rpg_equipment_strength 45 | /scoreboard players operation @s 40planet_rpg_speed += @s 40planet_rpg_equipment_speed 46 | /scoreboard players operation @s 40planet_rpg_mana += @s 40planet_rpg_equipment_mana 47 | stat.update_attribute() 48 | /scoreboard players operation @s 40planet_rpg_health -= @s 40planet_rpg_equipment_health 49 | /scoreboard players operation @s 40planet_rpg_strength -= @s 40planet_rpg_equipment_strength 50 | /scoreboard players operation @s 40planet_rpg_speed -= @s 40planet_rpg_equipment_speed 51 | /scoreboard players operation @s 40planet_rpg_mana -= @s 40planet_rpg_equipment_mana 52 | } 53 | 54 | 55 | def add_stat(var type, var value){ # 스텟 + value, 스텟포인트 - 1 56 | execute (if score "@s" "40planet_stat_point" matches ..0){ 57 | /tellraw @s {"text":"스텟포인트가 부족합니다","color":"red"} 58 | /execute at @s run playsound minecraft:block.note_block.bass weather @s ~ ~ ~ 1 1 59 | return 1 60 | } 61 | /scoreboard players add @s 40planet_rpg_^type& ^value& 62 | /scoreboard players remove @s 40planet_stat_point 1 63 | update_stat() 64 | } 65 | 66 | def click_2_19(){ # 체력 67 | execute(if items entity @s container.19 *){ 68 | return_item(19) 69 | } 70 | add_stat("health", 1) 71 | /return 1 72 | } 73 | def click_2_21(){ # 근력 74 | execute(if items entity @s container.21 *){ 75 | return_item(21) 76 | } 77 | add_stat("strength", 1) 78 | /return 1 79 | } 80 | def click_2_23(){ # 민첩 81 | execute(if items entity @s container.23 *){ 82 | return_item(23) 83 | } 84 | add_stat("speed", 1) 85 | /return 1 86 | } 87 | def click_2_25(){ # 마나 88 | execute(if items entity @s container.21 *){ 89 | return_item(25) 90 | } 91 | add_stat("mana", 1) 92 | /return 1 93 | } 94 | 95 | # 장비의 업그레이드 스텟 추가해주는 함수 96 | def update_equipment_stat(){ 97 | /scoreboard players set @s 40planet_rpg_equipment_health 0 98 | /scoreboard players set @s 40planet_rpg_equipment_strength 0 99 | /scoreboard players set @s 40planet_rpg_equipment_speed 0 100 | /scoreboard players set @s 40planet_rpg_equipment_mana 0 101 | 102 | /execute unless data storage 40planet:rpg players.^player_id&.armor run data modify storage 40planet:rpg players.^player_id&.armor set value [{}, {}, {}, {}, {}, {}, {}] 103 | /data modify storage 40planet:rpg players.armor set from storage 40planet:rpg players.^player_id&.armor 104 | var armor_data = get_data("storage", "40planet:rpg", "players.armor") 105 | var j = 0; 106 | while(j < 7){ 107 | /execute in minecraft:overworld run item replace block 15 -60 15 container.0 with air 108 | /execute in minecraft:overworld run item replace block 15 -60 15 container.1 with stone 109 | armor_data[j].Slot = 1b 110 | execute(in minecraft:overworld){set_data("block", "15 -60 15", "Items[0]", armor_data[j])} 111 | execute(in minecraft:overworld if data block "15 -60 15" "Items[0].components.'minecraft:custom_data'.upgrade"){ 112 | var upgrade = get_data("block", "15 -60 15", "Items[0].components.'minecraft:custom_data'.upgrade") 113 | var i = 0; 114 | var len = len(upgrade) 115 | while(i < len){ 116 | var type = upgrade[0].type 117 | var value = upgrade[0].value 118 | set_score("value", "40planet_num", value) 119 | /execute if score value 40planet_num matches 1.. run scoreboard players add @s 40planet_rpg_equipment_^type& ^value& 120 | /execute if score value 40planet_num matches ..0 run scoreboard players remove @s 40planet_rpg_equipment_^type& ^value& 121 | del(upgrade[0]) 122 | i = i + 1; 123 | } 124 | } 125 | j = j + 1; 126 | } 127 | update_stat() 128 | } 129 | 130 | # 갑옷 장착, 해제 함수 131 | def armor_slot(var slot, var idx){ 132 | /execute in minecraft:overworld run item replace block 15 -60 15 container.0 from entity @s container.^slot& 133 | execute(if score "is_correct_slot" "40planet_num" matches 0){ 134 | /execute at @s run playsound minecraft:item.armor.equip_iron weather @s ~ ~ ~ 135 | /data modify storage 40planet:rpg players.^player_id&.armor[^idx&] set value {} 136 | update_equipment_stat() 137 | return_item(slot) 138 | return 1 139 | } 140 | /execute store success score temp 40planet_num in minecraft:overworld run data modify storage 40planet:rpg players.^player_id&.armor[^idx&] set from block 15 -60 15 Items[0] 141 | /execute if score temp 40planet_num matches 1 at @s run playsound minecraft:item.armor.equip_iron weather @s ~ ~ ~ 142 | # update_armor_slot(slot, idx, true) 143 | update_equipment_stat() 144 | /scoreboard players set not_change_inv 40planet_num 1 145 | /clear @s *[minecraft:custom_data~{40planet_ui_^slot&:1b}] 146 | return 1 147 | } 148 | def click_3_11(){ # 투구 149 | # print("투구") 150 | /execute store result score is_correct_slot 40planet_num if items entity @s container.11 *[minecraft:custom_data~{40planet_helmet:1b}] 151 | return armor_slot(11, 0) 152 | } 153 | 154 | def click_4_13(){ # 무기 슬롯 155 | execute(unless items entity @s container.13 *[minecraft:custom_data~{40planet_equipment:1b}]){ 156 | return_item(13) 157 | return 1 158 | } 159 | 160 | /kill "98a261f6-84b5-4c36-ad3f-818aec8c7404" 161 | /summon armor_stand ~ ~ ~ {UUID:[I;-1734188554,-2068493258,-1388346998,-326339580]} 162 | 163 | /item replace block 15 -60 15 container.0 from entity @s container.13 164 | /execute store success score temp 40planet_num run data modify storage 40planet:rpg players.^player_id&.skill_item set from block 15 -60 15 Items[0] 165 | 166 | # 장비가 아닌 다른 것을 옮김 167 | execute(if score "temp" "40planet_num" matches 0 in minecraft:overworld){ # 인벤토리 -> 컴포넌트 168 | /item replace block 15 -60 15 container.1 from entity @s container.29 169 | /data modify block 15 -60 15 Items[0].components."minecraft:custom_data".skill.f set from block 15 -60 15 Items[1] 170 | /execute unless data block 15 -60 15 Items[1] run data modify block 15 -60 15 Items[0].components."minecraft:custom_data".skill.f set value {} 171 | /item replace block 15 -60 15 container.1 from entity @s container.31 172 | /data modify block 15 -60 15 Items[0].components."minecraft:custom_data".skill.click set from block 15 -60 15 Items[1] 173 | /execute unless data block 15 -60 15 Items[1] run data modify block 15 -60 15 Items[0].components."minecraft:custom_data".skill.click set value {} 174 | /item replace block 15 -60 15 container.1 from entity @s container.33 175 | /data modify block 15 -60 15 Items[0].components."minecraft:custom_data".skill.sneak_click set from block 15 -60 15 Items[1] 176 | /execute unless data block 15 -60 15 Items[1] run data modify block 15 -60 15 Items[0].components."minecraft:custom_data".skill.sneak_click set value {} 177 | /item replace entity @s container.13 from block 15 -60 15 container.0 178 | /execute store success score temp 40planet_num run data modify storage 40planet:rpg players.^player_id&.skill_item set from block 15 -60 15 Items[0] 179 | } 180 | # 장비를 옮김 181 | execute(if score "temp" "40planet_num" matches 1 in minecraft:overworld){ # 컴포넌트 -> 인벤토리 182 | /execute at @s run playsound minecraft:item.armor.equip_iron weather @s ~ ~ ~ 183 | /data modify entity "98a261f6-84b5-4c36-ad3f-818aec8c7404" HandItems[0] set from block 15 -60 15 Items[0].components."minecraft:custom_data".skill.f 184 | /execute if data block 15 -60 15 Items[0].components."minecraft:custom_data".skill.f run item replace entity @s container.29 from entity "98a261f6-84b5-4c36-ad3f-818aec8c7404" weapon 185 | /data modify entity "98a261f6-84b5-4c36-ad3f-818aec8c7404" HandItems[0] set from block 15 -60 15 Items[0].components."minecraft:custom_data".skill.click 186 | /execute if data block 15 -60 15 Items[0].components."minecraft:custom_data".skill.click run item replace entity @s container.31 from entity "98a261f6-84b5-4c36-ad3f-818aec8c7404" weapon 187 | /data modify entity "98a261f6-84b5-4c36-ad3f-818aec8c7404" HandItems[0] set from block 15 -60 15 Items[0].components."minecraft:custom_data".skill.sneak_click 188 | /execute if data block 15 -60 15 Items[0].components."minecraft:custom_data".skill.sneak_click run item replace entity @s container.33 from entity "98a261f6-84b5-4c36-ad3f-818aec8c7404" weapon 189 | } 190 | 191 | /scoreboard players set not_change_inv 40planet_num 1 192 | # print("스킬 장비칸") 193 | /clear @s *[custom_data~{40planet_ui_skill:1b}] 194 | /kill "98a261f6-84b5-4c36-ad3f-818aec8c7404" 195 | /execute in minecraft:overworld run item replace block 15 -60 15 container.0 with air 196 | /return 1 197 | } 198 | def click_4_29(){ # F 199 | /scoreboard players set not_change_inv 40planet_num 1 200 | /scoreboard players set temp 40planet_num 0 201 | /execute unless items entity @s container.29 *[minecraft:custom_data~{40planet_skill:1b}] run scoreboard players set temp 40planet_num 1 202 | /execute unless items entity @s container.13 *[minecraft:custom_data~{40planet_equipment:1b}] run scoreboard players set temp 40planet_num 1 203 | execute(if score "temp" "40planet_num" matches 1){ 204 | return_item(29) 205 | } 206 | /return 1 207 | } 208 | def click_4_31(){ # 우클릭 209 | /scoreboard players set not_change_inv 40planet_num 1 210 | /scoreboard players set temp 40planet_num 0 211 | /execute unless items entity @s container.31 *[minecraft:custom_data~{40planet_skill:1b}] run scoreboard players set temp 40planet_num 1 212 | /execute unless items entity @s container.13 *[minecraft:custom_data~{40planet_equipment:1b}] run scoreboard players set temp 40planet_num 1 213 | execute(if score "temp" "40planet_num" matches 1){ 214 | return_item(31) 215 | } 216 | /return 1 217 | } 218 | def click_4_33(){ # Shift + 우클릭 219 | /scoreboard players set not_change_inv 40planet_num 1 220 | /scoreboard players set temp 40planet_num 0 221 | /execute unless items entity @s container.33 *[minecraft:custom_data~{40planet_skill:1b}] run scoreboard players set temp 40planet_num 1 222 | /execute unless items entity @s container.13 *[minecraft:custom_data~{40planet_equipment:1b}] run scoreboard players set temp 40planet_num 1 223 | execute(if score "temp" "40planet_num" matches 1){ 224 | return_item(33) 225 | } 226 | /return 1 227 | } 228 | 229 | 230 | def summon_window(){ 231 | execute(summon minecraft:block_display){ 232 | /data merge entity @s {Tags:["rpg_window_marker","unset","40planet_gui_entity"]} 233 | /tp @s ~ ~ ~ ~180 0 234 | } 235 | execute(summon minecraft:text_display){ 236 | /data merge entity @s {Tags:["unset","40planet_gui_entity"],transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],scale:[7f,10f,1f],translation:[-.085f,1.5f,-.15f]}} 237 | /tp @s ~ ~ ~ ~180 0 238 | } 239 | execute(summon minecraft:text_display){ 240 | /data merge entity @s {Tags:["unset","40planet_gui_entity"],transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],scale:[.1f,.1f,1f],translation:[0f,1.7f,-.15f]},text:'{"text":"[ 스텟 ]","bold":true}',background:0} 241 | /tp @s ~ ~ ~ ~180 0 242 | } 243 | execute(summon minecraft:text_display){ 244 | /data merge entity @s {Tags:["unset","40planet_gui_entity"],transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],scale:[.1f,.1f,1f],translation:[0f,1.61f,-.15f]},text:'{"text":"[ 장비 ]","bold":true}',background:0} 245 | /tp @s ~ ~ ~ ~180 0 246 | } 247 | execute(summon minecraft:text_display){ 248 | /data merge entity @s {Tags:["unset","40planet_gui_entity"],transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],scale:[.1f,.1f,1f],translation:[0f,1.52f,-.15f]},text:'{"text":"[ 스킬 ]","bold":true}',background:0} 249 | /tp @s ~ ~ ~ ~180 0 250 | /data modify storage 40planet:rpg window.rotation set from entity @s Rotation 251 | } 252 | /execute rotated ~180 0 run summon minecraft:interaction ^ ^1.70 ^-.15 {Tags:["unset","40planet_gui_entity","stat"],height:.03f,width:.1f,response:1b} 253 | /execute rotated ~180 0 run summon minecraft:interaction ^ ^1.61 ^-.15 {Tags:["unset","40planet_gui_entity","equip"],height:.03f,width:.1f,response:1b} 254 | /execute rotated ~180 0 run summon minecraft:interaction ^ ^1.52 ^-.15 {Tags:["unset","40planet_gui_entity","skill"],height:.03f,width:.1f,response:1b} 255 | 256 | /scoreboard players operation #temp 40planet_num = @s 40planet_id 257 | execute(as @e[distance=..2,tag=unset]){ 258 | /scoreboard players operation @s 40planet_id = #temp 40planet_num 259 | /tag @s remove unset 260 | /data modify entity @s Rotation set from storage 40planet:rpg window.rotation 261 | } 262 | } 263 | 264 | def summon_stat_window(){ 265 | /scoreboard players operation #temp 40planet_num = @s 40planet_id 266 | execute(summon minecraft:text_display){ 267 | /data merge entity @s {Tags:["40planet_gui_entity","stat_window"],transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],scale:[7f,10f,1f],translation:[-.085f,1.5f,-.15f]}} 268 | /tp @s ~ ~ ~ ~ 0 269 | /scoreboard players operation @s 40planet_id = #temp 40planet_num 270 | } 271 | } 272 | 273 | def tick(){ 274 | /execute unless entity a3924728-f122-470f-977a-79ec38d81808 run summon item_display 0 -60 0 {UUID:[I;-1550694616,-249411825,-1753581076,953686024]} 275 | 276 | execute(as @a unless items entity @s container.17 *[minecraft:custom_data~{40planet_inv_btn:1b}] at @s){ 277 | summon_window() 278 | 279 | /clear @s command_block[minecraft:custom_data~{40planet_inv_btn:1b}] 280 | /execute in minecraft:overworld run item replace entity a3924728-f122-470f-977a-79ec38d81808 container.0 from entity @s container.17 281 | /item replace entity @s container.17 with command_block[minecraft:custom_data={40planet_inv_btn:1b}] 282 | /execute in minecraft:overworld unless items entity a3924728-f122-470f-977a-79ec38d81808 container.0 * run return 0 283 | /execute at @s anchored eyes positioned ^ ^ ^ run summon item ~ ~ ~ {PickupDelay:0s,Item:{id:"stone",count:1b},Tags:["40planet_rpg_item"]} 284 | execute(as @e[tag=40planet_rpg_item,limit=1]){ 285 | /execute in minecraft:overworld run item replace entity @s container.0 from entity a3924728-f122-470f-977a-79ec38d81808 container.0 286 | /tag @s remove 40planet_rpg_item 287 | } 288 | 289 | } 290 | 291 | execute(as @e[tag=40planet_gui_entity]){ 292 | execute(if entity @s[tag=rpg_window_marker] at @s unless entity @a[distance=..0.0001]){ 293 | /scoreboard players operation #temp 40planet_num = @s 40planet_id 294 | /execute as @e[tag=40planet_gui_entity,distance=..2] if score @s 40planet_id = #temp 40planet_num run kill @s 295 | /kill @s 296 | } 297 | 298 | execute(if entity @s[type=interaction] if data entity "@s" "interaction" at @s){ 299 | /scoreboard players operation #temp 40planet_num = @s 40planet_id 300 | /execute as @a if score @s 40planet_id = #temp 40planet_num run tag @s add 40planet_rpg_window_owner 301 | /execute if entity @s[tag=stat] rotated ~75 ~ positioned as @p[tag=40planet_rpg_window_owner] run function __namespace__:summon_stat_window 302 | /tag @a remove 40planet_rpg_window_owner 303 | /data remove entity @s interaction 304 | } 305 | } 306 | 307 | 308 | } -------------------------------------------------------------------------------- /rpg_planet/mob/health_bar.planet: -------------------------------------------------------------------------------- 1 | 2 | /scoreboard objectives add 40planet_health_bar_health dummy 3 | /scoreboard objectives add 40planet_pre_health dummy 4 | /scoreboard players set 10 40planet_num 10 5 | /scoreboard players set -1 40planet_num -1 6 | 7 | 8 | def health_bar_tick(){ 9 | /function __namespace__:tick_entity 10 | execute(as @s[tag=health_bar_display] unless predicate rpg_mob:vehicle){ 11 | /execute on passengers run kill @s 12 | /kill @s 13 | } 14 | } 15 | 16 | def detect(){ 17 | /scoreboard players set test 40planet_num 0 18 | /execute on passengers on passengers if entity @s[tag=green] run scoreboard players set test 40planet_num 1 19 | execute(if score "test" "40planet_num" matches 0 at @s){ 20 | /summon interaction ~ ~ ~ {Tags:["health_bar_display","unset"],height:0,width:0,Passengers:[{billboard:"vertical",transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],translation:[-1f,0.8f,0f],scale:[80f,8f,8f]},background:-16122112,Tags:["green"],id:"text_display",interpolation_duration:2,start_interpolation:0},{billboard:"vertical",transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],translation:[-1f,0.8f,-0.001f],scale:[80f,7.9f,7.9f]},background:-65536,Tags:["red"],id:"text_display"},{billboard:"vertical",transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],translation:[0f,1f,0f],scale:[1.5f,1.5f,1.5f]},background:0,Tags:["text"],shadow:1b,id:"text_display"}]} 21 | /ride @n[distance=..0.001,tag=unset] mount @s 22 | /execute on passengers run tag @s remove unset 23 | } 24 | } 25 | 26 | def set_health(){ 27 | /execute store result score @s 40planet_health_bar_health run data get entity @s Health 10 28 | execute(unless score "@s" "40planet_health_bar_health" = "@s" "40planet_pre_health"){ 29 | /scoreboard players operation @s 40planet_pre_health = @s 40planet_health_bar_health 30 | var max_health = get_score("@s", "40planet_rpg_health") 31 | /scoreboard players operation @s 40planet_health_bar_health = @s 40planet_rpg_health 32 | /scoreboard players operation @s 40planet_health_bar_health -= @s 40planet_reduced_health 33 | var health = get_score("@s", "40planet_health_bar_health") 34 | print("max_health :", max_health, "health :", health) 35 | var percentage = divide(health, max_health) 36 | /scoreboard players operation health 40planet_num = @s 40planet_health_bar_health 37 | /scoreboard players operation health 40planet_num /= 10 40planet_num 38 | /scoreboard players operation max_health 40planet_num = @s 40planet_rpg_health 39 | /scoreboard players operation max_health 40planet_num /= 10 40planet_num 40 | execute(on passengers on passengers){ 41 | execute(if entity @s[tag=green]){ 42 | /data modify entity @s start_interpolation set value 0 43 | set_data("entity", "@s", "transformation.scale[0]", float(percentage * 80.0)) 44 | print("percentage :", percentage, "scale :", float(percentage * 80.0)) 45 | } 46 | execute(if entity @s[tag=text]){ 47 | /data merge entity @s {text:'["",{"score":{"name":"health","objective":"40planet_num"},"color":"green"},{"text":"/","color":"green"},{"score":{"name":"max_health","objective":"40planet_num"},"color":"green"}]'} 48 | } 49 | } 50 | } 51 | 52 | } 53 | 54 | def tick_entity(){ 55 | execute(if entity @s[type=player]){ 56 | /tellraw @s {"text":"플레이어에게는 체력바를 표시할 수 없습니다", "color":"red"} 57 | return 0 58 | } 59 | detect() 60 | execute(if data entity "@s" "Health"){ set_health() } 61 | } -------------------------------------------------------------------------------- /rpg_planet/mob/mob.planet: -------------------------------------------------------------------------------- 1 | import health_bar 2 | import test 3 | import summon 4 | 5 | /scoreboard objectives add 40planet_reduced_health dummy 6 | /scoreboard objectives add 40planet_rpg_health dummy 7 | /scoreboard objectives add 40planet_is_death dummy 8 | /scoreboard objectives add 40planet_death_animation_len dummy 9 | /scoreboard players set -5 40planet_num -5 10 | 11 | 12 | def detect_death(){ 13 | # 체력 가져오기 14 | /execute store result score @s 40planet_reduced_health run data get entity @s Health 10 15 | /scoreboard players remove @s 40planet_reduced_health 10000 16 | /scoreboard players operation @s 40planet_reduced_health *= -5 40planet_num 17 | # 죽음 감지 18 | /execute if score @s 40planet_reduced_health >= @s 40planet_rpg_health run scoreboard players set @s 40planet_is_death 1 19 | # 죽음 애니메이션 길이 설정 20 | /scoreboard players operation temp 40planet_num = @s 40planet_death_animation_len 21 | /execute on passengers run scoreboard players operation @s 40planet_death_animation_len = temp 40planet_num 22 | } 23 | 24 | def mob_tick(){ 25 | # 죽음 감지 26 | detect_death() 27 | # 각 몬스터에게 맞는 tick 함수 실행 28 | execute(if entity @s[tag=40planet_test]){ test.test_tick() } 29 | 30 | } 31 | 32 | def mob_attack(){ 33 | /say attack 34 | # 각 몬스터에게 맞는 attack 함수 실행 35 | execute(if entity @s[tag=40planet_test]){ test.attack() } 36 | 37 | } 38 | 39 | # 엘리트 몹이 될 가능성이 있는 몹 타입 태그 40 | var mob_type = "#minecraft:undead" 41 | 42 | def tick(){ 43 | execute(as @e[type=!player]){ 44 | # 엘리트몹 설정 45 | /scoreboard players set is_mob 40planet_num 0 46 | /execute if entity @s[tag=,type=^mob_type&] run scoreboard players set is_mob 40planet_num 1 47 | execute(if score "is_mob" "40planet_num" matches 1){ 48 | /execute store result score temp 40planet_num run random value 1..1000 49 | execute(if score "temp" "40planet_num" matches ..100){ 50 | /tag @s add elite_mob 51 | /attribute @s minecraft:generic.scale base set 1.5 52 | /execute store result score temp 40planet_num run random value 1..4 53 | var loot_table_num = get_score("temp", "40planet_num") 54 | /data modify entity @s DeathLootTable set value "rpg:elite_mob^loot_table_num&" 55 | /effect give @s resistance infinite 0 true 56 | } 57 | /tag @s add at_e 58 | } 59 | execute(if entity @s[tag=40planet_rpg_mob]){ 60 | mob_tick() 61 | health_bar.health_bar_tick() 62 | } 63 | execute(if entity @s[tag=40planet_mob_display] unless predicate rpg_mob:vehicle){ 64 | /scoreboard players remove @s 40planet_death_animation_len 1 65 | /execute if score @s 40planet_death_animation_len matches ..0 run kill @s 66 | } 67 | execute(as @s[tag=health_bar_display] unless predicate rpg_mob:vehicle){ 68 | /execute on passengers run kill @s 69 | /kill @s 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /rpg_planet/mob/summon.planet: -------------------------------------------------------------------------------- 1 | 2 | def set_basic(){ 3 | /effect give @s invisibility infinite 0 true 4 | /attribute @s generic.max_health base set 1000 5 | /data modify entity @s Health set value 1000f 6 | /effect give @s resistance infinite 3 true 7 | /tag @s add 40planet_rpg_mob 8 | # 나중에 1.21.2 나오면 item_model 공기로 바꿔서 안 보이게 하기 9 | /item replace entity @s weapon with stone_button[enchantments={"rpg_mob:detect_attack":1}] 10 | } 11 | 12 | def orange_mushroom(){ 13 | execute(summon slime){ 14 | /data merge entity @s {DeathLootTable:"mob:entities/orange_mushroom",Tags:["mob","orange_mushroom","same_rotation"],Size:0,Health:1000f,Passengers:[{Tags:["mob_display"],id:"item_display",item:{id:"carrot_on_a_stick",Count:1b,components:{"minecraft:custom_model_data":1000001}}}]} 15 | set_basic() 16 | /scoreboard players set @s mob_health -10 17 | } 18 | } 19 | 20 | def blue_mushroom(){ 21 | execute(summon slime){ 22 | /data merge entity @s {DeathLootTable:"mob:entities/orange_mushroom",Tags:["mob","orange_mushroom","same_rotation"],Size:0,Health:1000f,Passengers:[{Tags:["mob_display"],id:"item_display",item:{id:"carrot_on_a_stick",Count:1b,components:{"minecraft:custom_model_data":1000001}}}]} 23 | set_basic() 24 | /scoreboard players set @s mob_health -10 25 | } 26 | } 27 | 28 | def test(){ 29 | execute(summon husk){ 30 | /summon text_display ~ ~ ~ {Tags:["unset","40planet_mob_display"],text:'{"text":"기본"}',billboard:"vertical",transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],scale:[2f,2f,2f],translation:[0f,.5f,0f]}} 31 | /ride @n[distance=..0.01,tag=unset] mount @s 32 | /execute on passengers run tag @s remove unset 33 | set_basic() 34 | /effect clear @s invisibility 35 | # 죽음 애니메이션 길이 1초로 설정 36 | /scoreboard players set @s 40planet_death_animation_len 20 37 | /data modify entity @s DeathLootTable set value "" 38 | /tag @s add 40planet_test 39 | # 체력 20으로 설정 40 | /scoreboard players set @s 40planet_rpg_health 200 41 | } 42 | } -------------------------------------------------------------------------------- /rpg_planet/mob/test.planet: -------------------------------------------------------------------------------- 1 | def death(){ 2 | /execute on passengers run data modify entity @s text set value '{"text":"죽음"}' 3 | /execute on passengers run ride @s dismount 4 | /tp @s ~ ~1000 ~ 5 | /kill @s 6 | } 7 | 8 | def attack(){ 9 | /scoreboard players set @s 40planet_num 10 10 | /execute on passengers run data modify entity @s text set value '{"text":"공격"}' 11 | } 12 | 13 | def test_tick(){ 14 | execute(if score "@s" "40planet_is_death" matches 1){ 15 | death() 16 | return 0 17 | } 18 | /execute if score @s 40planet_num matches 0.. run scoreboard players remove @s 40planet_num 1 19 | execute(if score "@s" "40planet_num" matches 0){ 20 | /execute on passengers run data modify entity @s text set value '{"text":"기본"}' 21 | } 22 | } -------------------------------------------------------------------------------- /rpg_planet/skill.planet: -------------------------------------------------------------------------------- 1 | 2 | # /scoreboard objectives add 40planet_mana_regeneration dummy 3 | /scoreboard objectives add 40planet_real_mana dummy 4 | /scoreboard objectives add 40planet_mana dummy 5 | /scoreboard objectives add 40planet_rpg_max_mana dummy 6 | /scoreboard objectives add 40planet_rpg_rightclick dummy 7 | 8 | /scoreboard players set 20 40planet_num 20 9 | /scoreboard players set 200 40planet_num 200 10 | 11 | def execute_function(var skill_slot){ 12 | /item replace block 15 -60 15 container.0 from entity @s weapon 13 | /data modify storage 40planet:rpg skill set from block 15 -60 15 Items[0].components.'minecraft:custom_data'.skill.^skill_slot& 14 | 15 | /execute store result score current_game_tick 40planet_num run time query gametime 16 | /execute store result score recent_used 40planet_num run data get storage 40planet:rpg skill.components.'minecraft:custom_data'.recent_used 17 | /execute store result score cooltime 40planet_num run data get storage 40planet:rpg skill.components.'minecraft:custom_data'.cooltime 18 | 19 | /scoreboard players operation current_game_tick 40planet_num -= recent_used 40planet_num 20 | execute(if score "current_game_tick" "40planet_num" < "cooltime" "40planet_num"){ 21 | /tellraw @s {"text":"쿨타임이 남았습니다","color":"red"} 22 | return 0 23 | } 24 | 25 | /execute store result score require_mana 40planet_num run data get storage 40planet:rpg skill.components.'minecraft:custom_data'.mana 26 | execute(if score "@s" "40planet_mana" < "require_mana" "40planet_num"){ 27 | /tellraw @s {"text":"마나가 부족합니다","color":"red"} 28 | return 0 29 | } 30 | 31 | 32 | /execute store result storage 40planet:rpg skill.components.'minecraft:custom_data'.recent_used int 1 run time query gametime 33 | /scoreboard players operation @s 40planet_mana -= require_mana 40planet_num 34 | /data modify block 15 -60 15 Items[0].components.'minecraft:custom_data'.skill.^skill_slot& set from storage 40planet:rpg skill 35 | /item replace entity @s weapon from block 15 -60 15 container.0 36 | var function = get_data("storage", "40planet:rpg", "skill.components.'minecraft:custom_data'.function") 37 | # print(function) 38 | /execute at @s run function ^function& 39 | } 40 | 41 | def weapon_f(){ 42 | /item replace block 15 -60 15 container.0 from entity @s weapon.offhand 43 | /scoreboard players set temp 40planet_num 0 44 | /execute if items entity @s weapon *[minecraft:custom_data~{40planet_equipment:1b}] run scoreboard players set temp 40planet_num 1 45 | execute(if score "temp" "40planet_num" matches 1){ 46 | /item replace block 15 -60 15 container.1 from entity @s weapon 47 | /item replace entity @s weapon from entity @s weapon.offhand 48 | /item replace entity @s weapon.offhand with air 49 | /execute at @s run summon item ~ ~1.5 ~ {PickupDelay:0s,Item:{id:"stone",count:1b},Tags:["40planet_rpg_item"]} 50 | execute(as @e[tag=40planet_rpg_item,limit=1]){ 51 | /item replace entity @s container.0 from block 15 -60 15 container.1 52 | /tag @s remove 40planet_rpg_item 53 | } 54 | } 55 | execute(if score "temp" "40planet_num" matches 0){ 56 | /item replace entity @s weapon.offhand from entity @s weapon 57 | /item replace entity @s weapon from block 15 -60 15 container.0 58 | } 59 | 60 | execute(if data entity "@s" "SelectedItem.components.'minecraft:custom_data'.skill.f.components.'minecraft:custom_data'.function"){ 61 | execute_function("f") 62 | } 63 | } 64 | 65 | def rightclick_advancement(){ 66 | /scoreboard players set @s 40planet_rpg_rightclick 1 67 | /advancement revoke @s only rpg:rightclick 68 | } 69 | 70 | def rightclick(){ 71 | /execute unless items entity @s weapon *[minecraft:custom_data~{40planet_equipment:1b}] run return fail 72 | /tag @s add rightclick 73 | 74 | execute(if predicate rpg:sneaking if data entity "@s" "SelectedItem.components.'minecraft:custom_data'.skill.sneak_click.components.'minecraft:custom_data'.function"){ 75 | execute_function("sneak_click") 76 | # var function = get_data("entity", "@s", "SelectedItem.components.'minecraft:custom_data'.skill.sneak_click.components.'minecraft:custom_data'.function") 77 | # /execute at @s run function ^function& 78 | } 79 | execute(unless predicate rpg:sneaking if data entity "@s" "SelectedItem.components.'minecraft:custom_data'.skill.click.components.'minecraft:custom_data'.function"){ 80 | execute_function("click") 81 | # var function = get_data("entity", "@s", "SelectedItem.components.'minecraft:custom_data'.skill.click.components.'minecraft:custom_data'.function") 82 | # /execute at @s run function ^function& 83 | } 84 | } 85 | 86 | 87 | 88 | def tick(){ 89 | execute(as @a){ 90 | # F 스킬 감지 91 | /execute if items entity @s weapon.offhand *[minecraft:custom_data~{40planet_equipment:1b}] run function __namespace__:weapon_f 92 | # 우클릭 감지 93 | /execute if score @s[tag=!rightclick] 40planet_rpg_rightclick matches 1 run function __namespace__:rightclick 94 | /execute if score @s 40planet_rpg_rightclick matches 0 run tag @s remove rightclick 95 | 96 | # 마나 회복 97 | # 마나 스텟 1 = 10 최대마나, 1초당 1 마나 회복 = 1틱 당 1/20 마나 회복 = 틱당 1 real_mana 회복 98 | # real_mana = mana * 20 99 | # /scoreboard players operation @s 40planet_mana_regeneration = @s 40planet_rpg_mana 100 | /scoreboard players operation @s 40planet_rpg_max_mana = @s 40planet_rpg_mana 101 | /scoreboard players operation @s 40planet_rpg_max_mana += @s 40planet_rpg_equipment_mana 102 | /scoreboard players operation @s 40planet_rpg_max_mana *= 200 40planet_num 103 | 104 | /scoreboard players operation temp 40planet_mana = @s 40planet_real_mana 105 | /scoreboard players operation temp 40planet_mana /= 20 40planet_num 106 | execute(unless score "temp" "40planet_mana" = "@s" "40planet_mana"){ 107 | /scoreboard players operation @s 40planet_real_mana = @s 40planet_mana 108 | /scoreboard players operation @s 40planet_real_mana *= 20 40planet_num 109 | } 110 | # /scoreboard players operation @s 40planet_real_mana += @s 40planet_mana_regeneration 111 | /scoreboard players operation @s 40planet_real_mana += @s 40planet_rpg_mana 112 | /scoreboard players operation @s 40planet_real_mana += @s 40planet_rpg_equipment_mana 113 | /execute if score @s 40planet_real_mana > @s 40planet_rpg_max_mana run scoreboard players operation @s 40planet_real_mana = @s 40planet_rpg_max_mana 114 | /scoreboard players operation @s 40planet_mana = @s 40planet_real_mana 115 | /scoreboard players operation @s 40planet_mana /= 20 40planet_num 116 | 117 | /execute if entity @s[tag=show_mana] run title @s actionbar [{"text":"현재 마나: ","color":"aqua"},{"score":{"objective":"40planet_mana","name":"@s"}}] 118 | } 119 | /scoreboard players set @a 40planet_rpg_rightclick 0 120 | } -------------------------------------------------------------------------------- /rpg_planet/skills.planet: -------------------------------------------------------------------------------- 1 | /scoreboard objectives add dash_cool dummy 2 | 3 | def dash(){ 4 | 5 | 6 | # "f35ac18d-c25b-4091-8e16-83071bd82518" 아이템 디티티 7 | # "4aa462f2-b7e4-4435-ad1f-995d09fd60f8" 마커1 8 | # "10856e46-c224-41bb-961d-5c25c45b3122" 마커2 9 | # "c6ce5480-f883-49e6-86e7-cdff30fae2c1" 눈덩이 10 | /summon item_display ~ ~10 ~ {UUID:[I;-212156019,-1034207087,-1911127289,467150104],width:0f,height:0f,Tags:[dash.6626.item,dash.6626.entity],Passengers:[{id:"minecraft:snowball",UUID:[I;-959556480,-125613594,-2031628801,821748417],Tags:[dash.6626.snow,dash.6626.entity],Passengers:[{id:"minecraft:marker",Tags:[dash.6626.circ,dash.6626.circ1,dash.6626.entity],UUID:[I;1252287218,-1209777099,-1390438051,167600376]},{id:"minecraft:marker",Tags:[dash.6626.circ,dash.6626.circ2,dash.6626.entity],UUID:[I;277179974,-1037811269,-1776460763,-1000656606]}]}],item:{id:"minecraft:grass_block",count:1,components:{"minecraft:custom_data":{ejalepdlxj:1}}}} 11 | /execute positioned ~ ~10 ~ facing ^ ^1 ^ run tp "4aa462f2-b7e4-4435-ad1f-995d09fd60f8" ~ ~ ~ ~ ~ 12 | /execute positioned ~ ~10 ~ facing ^ ^1 ^ facing ^ ^ ^-1 run tp "10856e46-c224-41bb-961d-5c25c45b3122" ~ ~ ~ ~ ~ 13 | /execute positioned ~ ~10 ~ as "c6ce5480-f883-49e6-86e7-cdff30fae2c1" on passengers at @s positioned ^ ^ ^1 on vehicle on passengers rotated as @s positioned ^1 ^ ^ facing entity @s feet positioned as @s positioned ^ ^ ^1 on vehicle on passengers rotated as @s positioned ^ ^ ^1 facing entity @s feet positioned as @s positioned ^ ^ ^1 on vehicle on passengers rotated as @s positioned ^ ^ ^1 facing entity @s feet positioned as @s positioned ^ ^ ^1 on vehicle on passengers rotated as @s positioned ^ ^ ^1 facing entity @s feet positioned as @s positioned ^ ^ ^1 positioned as @s positioned ~ ~-10 ~ run particle minecraft:end_rod ~ ~ ~ ^ ^ ^100000000 .000000001 0 14 | /execute as "f35ac18d-c25b-4091-8e16-83071bd82518" on passengers on passengers run kill @s 15 | /execute as "f35ac18d-c25b-4091-8e16-83071bd82518" on passengers run kill @s 16 | /kill "f35ac18d-c25b-4091-8e16-83071bd82518" 17 | 18 | /execute if entity @s[gamemode=survival] run scoreboard players set gamemode 40planet_num 0 19 | /execute if entity @s[gamemode=creative] run scoreboard players set gamemode 40planet_num 1 20 | /execute if entity @s[gamemode=adventure] run scoreboard players set gamemode 40planet_num 2 21 | /gamemode creative 22 | /tp @s ~ ~1000 ~ 23 | /execute at @s anchored eyes positioned ^ ^ ^-1 summon minecraft:end_crystal run damage @s 10 24 | /tp @s ~ ~ ~ 25 | 26 | 27 | /execute if score gamemode 40planet_num matches 0 run gamemode survival 28 | /execute if score gamemode 40planet_num matches 1 run gamemode creative 29 | /execute if score gamemode 40planet_num matches 2 run gamemode adventure 30 | } 31 | 32 | def heal(){ 33 | /effect give @s minecraft:instant_health 1 0 true 34 | } 35 | def resistance(){ 36 | /effect give @s minecraft:resistance 5 0 true 37 | } 38 | def absorption(){ 39 | /effect give @s minecraft:absorption 20 1 true 40 | } 41 | def berserker(){ 42 | /damage @s 10 minecraft:out_of_world 43 | /effect give @s strength 10 1 true 44 | } -------------------------------------------------------------------------------- /rpg_planet/stat.planet: -------------------------------------------------------------------------------- 1 | /scoreboard objectives add 40planet_rpg_level dummy 2 | /scoreboard objectives add 40planet_level level 3 | /scoreboard objectives add 40planet_stat_point dummy 4 | /scoreboard objectives add 40planet_rpg_health dummy 5 | /scoreboard objectives add 40planet_rpg_strength dummy 6 | /scoreboard objectives add 40planet_rpg_speed dummy 7 | /scoreboard objectives add 40planet_rpg_mana dummy 8 | 9 | /scoreboard players set point_per_level 40planet_num 1 10 | 11 | def tick(){ 12 | execute(as @a){ 13 | /execute unless score @s 40planet_rpg_level = @s 40planet_rpg_level run function __namespace__:set_scoreboard 14 | execute(if score "@s" "40planet_level" > "@s" "40planet_rpg_level"){ # 레벨업 15 | /scoreboard players operation temp 40planet_num = @s 40planet_level 16 | /scoreboard players operation temp 40planet_num -= @s 40planet_rpg_level 17 | /scoreboard players operation temp 40planet_num *= point_per_level 40planet_num 18 | /scoreboard players operation @s 40planet_stat_point += temp 40planet_num 19 | /scoreboard players operation @s 40planet_rpg_level = @s 40planet_level 20 | /function __namespace__:save 21 | } 22 | } 23 | } 24 | 25 | def update_attribute(){ 26 | var health = get_score("@s", "40planet_rpg_health") + 20 27 | var strength = get_score("@s", "40planet_rpg_strength") + 1 28 | /scoreboard players add @s 40planet_rpg_speed 20 29 | var speed = multiply(get_score("@s", "40planet_rpg_speed"), 0.005) 30 | var mining_speed = multiply(get_score("@s", "40planet_rpg_speed"), 0.05) 31 | /scoreboard players remove @s 40planet_rpg_speed 20 32 | /attribute @s minecraft:generic.max_health base set ^health& 33 | /attribute @s minecraft:generic.attack_damage base set ^strength& 34 | /attribute @s minecraft:generic.movement_speed base set ^speed& 35 | /attribute @s minecraft:player.block_break_speed base set ^mining_speed& 36 | } 37 | 38 | def set_scoreboard(){ 39 | var uuid = get_data("entity", "@s", "UUID") 40 | /scoreboard players set is_uuid_exist 40planet_num 0 41 | /execute if data storage 40planet:stat player."^uuid&".id run scoreboard players set is_uuid_exist 40planet_num 1 42 | # uuid가 있을 때 43 | execute(if score "is_uuid_exist" "40planet_num" matches 1){ 44 | /execute store result score @s 40planet_rpg_level run data get storage 40planet:stat player."^uuid&".level 45 | /execute store result score @s 40planet_rpg_health run data get storage 40planet:stat player."^uuid&".health 46 | /execute store result score @s 40planet_rpg_strength run data get storage 40planet:stat player."^uuid&".strength 47 | /execute store result score @s 40planet_rpg_speed run data get storage 40planet:stat player."^uuid&".speed 48 | /execute store result score @s 40planet_rpg_mana run data get storage 40planet:stat player."^uuid&".mana 49 | /execute store result score @s 40planet_stat_point run data get storage 40planet:stat player."^uuid&".stat_point 50 | } 51 | # uuid가 없을 때 52 | execute(if score "is_uuid_exist" "40planet_num" matches 0){ 53 | /scoreboard players set @s 40planet_rpg_level 0 54 | /scoreboard players set @s 40planet_rpg_health 0 55 | /scoreboard players set @s 40planet_rpg_strength 0 56 | /scoreboard players set @s 40planet_rpg_speed 0 57 | /scoreboard players set @s 40planet_rpg_mana 0 58 | /scoreboard players set @s 40planet_stat_point 0 59 | /data modify storage 40planet:stat player."^uuid&" set value {health:0,level:0,strength:0,speed:0,mana:0,stat_point:0} 60 | } 61 | } 62 | 63 | def save_all(){ 64 | /execute as @a run function __namespace__:save 65 | } 66 | def save(){ 67 | var uuid = get_data("entity", "@s", "UUID") 68 | /execute store result storage 40planet:stat player.uuid.level int 1 run scoreboard players get @s 40planet_rpg_level 69 | /execute store result storage 40planet:stat player.uuid.health int 1 run scoreboard players get @s 40planet_rpg_health 70 | /execute store result storage 40planet:stat player.uuid.strength int 1 run scoreboard players get @s 40planet_rpg_strength 71 | /execute store result storage 40planet:stat player.uuid.speed int 1 run scoreboard players get @s 40planet_rpg_speed 72 | /execute store result storage 40planet:stat player.uuid.mana int 1 run scoreboard players get @s 40planet_rpg_mana 73 | /execute store result storage 40planet:stat player.uuid.stat_point int 1 run scoreboard players get @s 40planet_stat_point 74 | /data modify storage 40planet:stat player."^uuid&" set from storage 40planet:stat player.uuid 75 | } 76 | 77 | def reset(){ 78 | var uuid = get_data("entity", "@s", "UUID") 79 | /data remove storage 40planet:stat player."^uuid&" 80 | /scoreboard players set @s 40planet_rpg_level 0 81 | /scoreboard players set @s 40planet_rpg_health 0 82 | /scoreboard players set @s 40planet_rpg_strength 0 83 | /scoreboard players set @s 40planet_rpg_speed 0 84 | /scoreboard players set @s 40planet_rpg_mana 0 85 | /scoreboard players set @s 40planet_stat_point 0 86 | /data modify storage 40planet:stat player."^uuid&" set value {health:0,level:0,strength:0,speed:0,mana:0,stat_point:0} 87 | update_attribute() 88 | save() 89 | } -------------------------------------------------------------------------------- /web/image/file.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/image/folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/image/global.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /web/image/namespace.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/image/output.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/image/version.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Comet Compiler 6 | 7 | 8 | 9 | 10 | 11 | 15 |
16 |
17 |
18 |
19 |
20 |
21 | 22 | Select file to compile 23 |
24 | 25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | Select folder to locate output 34 |
35 | 36 |
37 | 38 | 39 |
40 |
41 | 42 | Select minecraft version 43 | 52 |
53 |
54 | 55 | Input namespace. Capitalized character will be force-lowercased. 56 | 57 |
58 |
59 | 60 | 65 |
66 |
67 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /web/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;200;300;400;500;600;700;800;900&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box !important; 5 | } 6 | 7 | nav { 8 | display: flex; 9 | flex-direction: row; 10 | justify-content: space-between; 11 | align-items: center; 12 | } 13 | 14 | nav > img { 15 | width: 35px !important; 16 | } 17 | 18 | body { 19 | padding: 10px; 20 | font-family: "Noto Sans KR"; 21 | background-color: aliceblue; 22 | } 23 | 24 | label { 25 | display: flex; 26 | flex-direction: row; 27 | gap: 5px; 28 | font-weight: 600; 29 | font-size: 23px; 30 | } 31 | 32 | img { 33 | width: 30px; 34 | } 35 | 36 | h1 { 37 | font-weight: 800; 38 | font-size: 35px; 39 | } 40 | 41 | #compile-btn { 42 | width: 100%; 43 | font-size: 18px; 44 | font-weight: 600; 45 | padding: 10px; 46 | background-color: dodgerblue; 47 | color: white; 48 | border-radius: 10px; 49 | border: 1px solid transparent; 50 | 51 | &:hover { 52 | background-color: rgb(54, 155, 255); 53 | } 54 | } 55 | 56 | #controller { 57 | margin-top: 15px; 58 | margin-bottom: 15px; 59 | } 60 | 61 | #controller > div { 62 | display: flex; 63 | flex-direction: column; 64 | margin-bottom: 10px; 65 | } 66 | 67 | #file { 68 | background-color: dodgerblue; 69 | font-size: 18px; 70 | padding: 10px 20px; 71 | color: white; 72 | border-radius: 10px; 73 | border: 1px solid transparent; 74 | font-weight: 600; 75 | 76 | &:hover { 77 | background-color: rgb(54, 155, 255); 78 | } 79 | } 80 | 81 | #folder { 82 | background-color: dodgerblue; 83 | font-size: 18px; 84 | padding: 10px 20px; 85 | color: white; 86 | border-radius: 10px; 87 | border: 1px solid transparent; 88 | font-weight: 600; 89 | 90 | &:hover { 91 | background-color: rgb(54, 155, 255); 92 | } 93 | } 94 | 95 | #version { 96 | font-size: 18px; 97 | background-color: rgba(30, 143, 255, 0.1); 98 | border: 1px solid #000000; 99 | border-radius: 5px; 100 | padding: 5px; 101 | } 102 | 103 | #namespace { 104 | font-size: 18px; 105 | background-color: rgba(30, 143, 255, 0.1); 106 | border: 1px solid #000000; 107 | border-radius: 5px; 108 | padding: 5px; 109 | } 110 | 111 | .button > div { 112 | display: flex; 113 | flex-direction: row; 114 | justify-content: space-between; 115 | align-items: center; 116 | } 117 | 118 | .button > div > div { 119 | display: flex; 120 | flex-direction: column; 121 | } 122 | 123 | .result { 124 | font-size: 15px; 125 | font-family: monospace; 126 | font-weight: 600; 127 | } 128 | 129 | .warning { 130 | color: red; 131 | font-weight: 600; 132 | } 133 | 134 | .compile-error-result { 135 | margin-top: 10px; 136 | font-family: monospace; 137 | width: 100%; 138 | height: 300px; 139 | background-color: rgba(30, 143, 255, 0.1); 140 | border: 1px solid #000000; 141 | border-radius: 10px; 142 | padding: 5px; 143 | overflow-wrap: break-word; 144 | white-space: break-spaces; 145 | } 146 | 147 | #output { 148 | margin-top: 10px; 149 | width: 100%; 150 | display: flex; 151 | flex-direction: column; 152 | } 153 | 154 | #output-show-output { 155 | background-color: dodgerblue; 156 | font-size: 18px; 157 | padding: 10px 20px; 158 | color: white; 159 | border-radius: 10px; 160 | border: 1px solid transparent; 161 | font-weight: 600; 162 | 163 | &:hover { 164 | background-color: rgb(54, 155, 255); 165 | } 166 | } 167 | 168 | code { 169 | font-weight: 600; 170 | font-size: 15px; 171 | } --------------------------------------------------------------------------------