Skip to content

QUAM-12/Mooster

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 

Repository files navigation

Mooster

📖 Description

마인크래프트에서 관전 모드(spectator)보다 더 빠르게 이동할 수 있도록 도와주는 유틸리티 도구입니다.

불러오기: /reload
삭제하기: /function mooster:uninstall {key:QUAM12}
아이템 얻기: /function mooster:a-item, /trigger Mooster.Item

⚙️ 기능

1. 아이템

/function mooster:a-item 명령어 또는 /trigger Mooster.Item 명령어를 이용하여, 아이템을 얻을 수 있습니다. F 키(다른 손과 아이템 맞바꾸기)를 누르면 비행 모드를 교체할 수 있습니다. (기본 | 겉날개)

2. 이동

아이템을 들고 우클릭을 누르면 날아다닐 수 있습니다.

How

* 아래는 무스터의 원리 설명입니다.
* 명령어 입문자에게는 다소 난해할 수 있습니다.
* 아래의 모든 명령어는 "함수" 사용을 전제로 구성됩니다. (커맨드 블록에서 무스터의 수정 및 제작은 고려하지 않습니다)
* 원리 설명은 마인크래프트 1.19.4 이상 버전을 기준으로 소개됩니다. 이하 버전에서는 이 방법을 사용할 수 없습니다.

무스터의 근간이 되는 "날아다니는 기능""엔드 크리스탈 넉백"을 이용해 구축됩니다.
"엔드 크리스탈 넉백"end_crystal0틱 이내로 폭발시켜 사용자가 원하는 방향, 힘으로 플레이어를 날릴 수 있도록 하는 기믹이며,
이를 이용해 플레이어는 여러 다양한 움직임(Motion)을 구사할 수 있습니다.

기본적으로 코드의 전체적인 흐름은 아래와 같습니다.

게임 모드를 저장한다. -> 게임 모드를 크리에이티브로 변경한다. -> 현재 위치에서 ~1000만큼 순간이동 시킨다. -> 엔드 크리스탈을 소환하고 폭발시킨다. -> 엔드 크리스탈이 터진 위치에서 ~-1000만큼 순간이동 시킨다. -> 저장한 게임 모드를 적용한다.

실제 코드는 다음과 같습니다. (구문 최적화 완료됨)
+ (2024. 12. 15. 수정됨) 스코어 보드로 게임 모드를 저장하는 것보단 태그가 접근이 더 빠르겠네요;;

execute if entity @s[gamemode=survival] run scoreboard players set #GameType <Objective> 0
execute if entity @s[gamemode=creative] run scoreboard players set #GameType <Objective> 1
execute if entity @s[gamemode=adventure] run scoreboard players set #GameType <Objective> 2

gamemode creative

tp @s ~ ~1000 ~

execute positioned ^ ^ ^-1 summon end_crystal run damage @s 1 generic_kill

execute at @s run tp @s ~ ~-1000 ~

execute if score #GameType <Objective> matches 0 run gamemode survival
execute if score #GameType <Objective> matches 1 run gamemode creative
execute if score #GameType <Objective> matches 2 run gamemode adventure

이것이 무스터를 구성하는 "엔드 크리스탈 넉백"의 가장 기본적인 형태입니다.
여러 궁금증을 풀어보면서 코드를 살펴보도록 하겠습니다.

  • 게임 모드는 왜 크리에이티브로 변경하는가?

    크리에이티브로 모드를 변경하는 이유는 크게 2가지로 사망 방지와 불필요한 효과 제거입니다.

    1. 엔드 크리스탈은 서바이벌과 모험 모드의 플레이어에게 대미지를 부여합니다.
      거리가 꽤나 멀지 않으면 플레이어는 엔드 크리스탈의 폭발 대미지로 인해 죽게 될 것입니다.
      그렇다면, 저항을 걸어서 무효화 하면 되지 않냐고 생각하실 수 있습니다. 그러나, ii. 번 이유 때문에 저항을 걸어 무효화 할 수 없습니다.
    2. 저항을 적용한 뒤, 엔드 크리스탈을 0틱 이내로 폭발시켜 대미지를 입으면 플레이어의 화면이 잠깐 흔들리며,
      플레이어가 다치는 소리까지 발생하기 때문에 시각적으로 불편하고 거슬립니다.
      다른 해결법으로 우회하기보다는 간편하게 게임 모드를 변경하는 것으로 대미지 효과를 제거할 수 있고 관리하기도 더 편합니다.
  • ~1000 좌표 위로 순간이동하는가?

    ~1000 좌표로 이동하는 이유는 엔드 크리스탈이 주위 블록을 무조건적으로 파괴시키기 때문입니다. (=TNT, 크리퍼는 mobGriefing에 의해 제어됩니다)

    // 엔드 크리스탈
    serverlevel.explode(this, damagesource1, (ExplosionDamageCalculator)null, this.getX(), this.getY(), this.getZ(), 6.0F, false, Level.ExplosionInteraction.BLOCK); // 폭발 상호작용 = 블록
    
    // 크리퍼
    serverlevel.explode(this, this.getX(), this.getY(), this.getZ(), (float)this.explosionRadius * f, Level.ExplosionInteraction.MOB); // 폭발 상호작용 = 몹
    
    // 폭발 설정
    switch (level_explosioninteraction) {
       case NONE:
          var10000 = Explosion.BlockInteraction.KEEP; // 아무 블록도 부수지 않습니다.
          break;
       case BLOCK:
          var10000 = this.getDestroyType(GameRules.RULE_BLOCK_EXPLOSION_DROP_DECAY); // 블록을 확정적으로 떨굴지 확률적으로 떨굴지를 결정합니다. (블록을 무조건 부숩니다)
          break;
       case MOB:
          var10000 = this.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? this.getDestroyType(GameRules.RULE_MOB_EXPLOSION_DROP_DECAY) : Explosion.BlockInteraction.KEEP; // 블록을 확정적으로 떨굴지 확률적으로 떨굴지를 결정합니다. (블록을 부수는 건 mobGriefing 규칙이 결정합니다)
          break;
       case TNT:
          var10000 = this.getDestroyType(GameRules.RULE_TNT_EXPLOSION_DROP_DECAY); // 블록을 확정적으로 떨굴지 확률적으로 떨굴지를 결정합니다. (블록을 무조건 부숩니다)
          break;
       case TRIGGER:
          var10000 = Explosion.BlockInteraction.TRIGGER_BLOCK; // 어떠한 블록을 변경할 수 있는지를 결정합니다. (돌풍구 -> 레버, 다락문 상호작용)
          break;
    }
  • execute summon을 사용하는가?

    코드 가독성과 간결화 및 최적화를 위함입니다. 위 코드의 경우,

    ...
    
    execute positioned ^ ^ ^-1 summon end_crystal run damage @s 1 generic_kill
    
    ...

    는 다음 코드로 대체할 수 있습니다.

    ...
    
    summon end_crystal ^ ^ ^-1 {Tags:[end_crystal]}
    damage @e[limit=1,tag=end_crystal,distance=..4,type=end_crystal] 1 generic_kill
    
    ...

    그러나, execute summon을 이용해 압축한 코드보다 읽기 어려우며, 선택자 탐색 비용을 소모하기 때문에 성능에 좋지 않습니다.
    따라서, execute summon을 이용해 코드를 압축하고 간결하게 재구성 했습니다.


실사용

무스터는 다른 편의적인 기능 추가와 버그 때문에 위 코드에서 약간 수정된 버전을 사용합니다.

  • 이는 플레이어의 역량에 따라 다릅니다.

실제로 무스터 데이터 팩을 살펴보면서 무엇을 변경했는지 알아보겠습니다.

변경점 1

게임 모드를 저장하기 전 플레이어의 크기를 1로 초기화 하는 코드를 추가했습니다.

attribute @s generic.scale base set 1

이는 크기가 커지면서 잘못된 위치에 소환되는 엔드 크리스탈을 원천 봉쇄하고,
크기가 커짐으로 인해 폭발 연산에 사용되는 AABB 히트박스 랙을 최소화 하기 위함입니다.

변경점 2

게임 모드를 크리에이티브로 변경하기 전, 모험 모드로 변경하는 코드를 추가했습니다.

...

gamemode adventure <- Added
gamemode creative

...

플레이어가 날고 있는 상태라면(크리에이티브와 관전 모드) 넉백이 정상적으로 작용하지 않기 때문에 모험 모드로 변경하여,
현재 플레이어의 flying을 해제해 어떠한 경우든지 넉백을 받을 수 있도록 하기 위함입니다.

  • TIP: gamemode adventuregamemode spectator로 변경하면, 플레이어가 날고 있는 상태로 만들 수 있습니다.

변경점 3

폭발 소리를 제거하는 코드를 추가했습니다.

...

stopsound @s * entity.generic.explode

...

플레이어의 시선 피치를 -90으로 지정하고, 무스터를 사용하면 발생하는 조그마한
폭발 소리가 거슬려서 사용자들에게 불편함을 줄 수 있기 때문에 과감히 소리를 제거했습니다.


유의점

* "함수"를 사용하는 상황에서 발생하는 문제를 기술합니다.

1. /teleport와 함수 내에서 위치 어긋남에 대한 문제

"엔드 크리스탈 넉백"을 수정하여 본인만의 시스템을 구축하거나, 사용할 때 유의해야 할 사항이 있습니다.
/teleport, /tp 명령어를 사용 시, 함수에서는 순간이동한 뒤, 좌표의 변경된 사항이 하단의 구문에 영향을 주지 않습니다.
겁나 어렵게 설명했는데 쉽게 말해 무슨 뜻이냐면

예를 들어, 아래 함수가 작성되어 있으며, 플레이어가 10 0 10 위치에 있다고 가정해 보겠습니다.

tp @s 0 0 0
tp @s ~ ~ ~

플레이어가 위의 함수를 실행하면 0 0 0으로 이동해야 할 것 같지만, 그렇지 않습니다.
함수는 초기 실행 대상의 좌표를 종속하기 때문에 /teleport 명령어를 사용하여,
위치를 변경해도 변경된 위치가 바로 밑 구문에 영향을 미치지 않는다는 것입니다.

이를 해결하는 방법으로는 execute at @s을 사용하는 것입니다.
/teleport로 변경된 좌표가 정상적으로 적용되어 성공적으로 플레이어를 0 0 0으로 이동시킵니다.

실사용/변경점...에서 언급하지는 않았지만, 무스터 데이터 팩을 뜯어보면 최초 1
좌표를 상승시키는 구문을 제외한 위치를 사용하는 대부분의 기능은 execute at @s을 추가한 것을 확인할 수 있습니다.

2. 게임 모드 변경 로그에 대한 문제

앞서 대미지와 기타 효과를 제거하기 위해 플레이어의 게임 모드를 변경하는 구문을 추가했습니다.
데이터 팩을 기준으로 설명하는 바람에 로그는 따로 발생하지 않아 언급은 하지 않았지만,
아래와 같이 코드를 작성하면 게임 모드를 변경할 때마다 표시되는 자신의 게임 모드를 [게임 모드]로 설정했습니다 피드백을 제거할 수 있습니다.

execute as @a[조건] run gamemode creative

반면, 아래와 같이 코드를 작성하면 피드백이 표시됩니다.

gamemode creative @a[조건]

커맨드 블록에서도 구현할 수 있기에 혹시나 해서 덧붙인 설명입니다.

Fin.

About

관전 모드보다 빠른 이동기

Resources

Stars

Watchers

Forks

Packages

No packages published