diff --git "a/assets/faqs/\321\200\320\265\320\271\320\272\320\260\321\201\321\202/\321\200\320\265\320\271\320\272\320\260\321\201\321\202.md" "b/assets/faqs/\321\200\320\265\320\271\320\272\320\260\321\201\321\202/\321\200\320\265\320\271\320\272\320\260\321\201\321\202.md" new file mode 100644 index 0000000..d25843b --- /dev/null +++ "b/assets/faqs/\321\200\320\265\320\271\320\272\320\260\321\201\321\202/\321\200\320\265\320\271\320\272\320\260\321\201\321\202.md" @@ -0,0 +1,73 @@ +## {anchor} Что такое рейкаст и как им пользоваться? +Рейкаст - это луч, который выпускается в определённом направлении (чаще всего по направлению взгляда игрока), который позволяет вычислять, на какой блок или сущность смотрит игрок, запускать разные команды по пути луча и по его столкновению с сущностью/блоком. Этот луч проходит мгновенно (меньше чем за тик), поэтому если вам нужно узнать, как сделать постепенный луч, то смотрите факьюшку `?слоукаст` (она ещё не написана). + +### Устройство рейкаста +Рейкаст работает в первую очередь за счёт рекурсивной функции в датапаке (функции, которая запускает саму себя), и с каждым запуском себя расположение запуска функции передвигается немного вперёд. В этой факьюшке рассмотрим базовый пример рейкаста, где можно настроить максимальную длину луча, столкновение с сущностью и блоком, и запуск команд по пути луча. +1. Для начала создадим скорборд для рейкаста: +{mcf_load}`load.mcf`: +```ansi +scoreboard objectives add raycast dummy +``` +2. Функция запуска рейкаста (запускаем эту функцию от лица сущности, от которой должен идти рейкаст): +{mcf}`raycast/launch.mcf`: +```ansi +# Выдаём сущности временный тег raycaster, чтоб рейкаст не мог столкнуться с тем, кто его запустил +tag @s add raycaster +# Выставляем количество шагов рейкаста. В этом примере сделаем максимальную длину рейкаста - 100 блоков, а каждый шаг рейкаста будет длиной в 0.1 блок, поэтому 100/0.1=1000 +scoreboard players set @s raycast 1000 +# Выставляем позицию запуска рейкаста на глазах сущности и запускаем основную функцию рейкаста +execute at @s anchored eyes positioned ^ ^ ^ run function namespace:raycast/ray +# Убираем временный тег +tag @s remove raycaster +``` +---separator--- +3. Основная функция рейкаста. В этом примере сделаем максимальную длину рейкаста - 100 блоков, а каждый шаг рейкаста будет длиной в 0.1 блок +{mcf}`raycast/ray.mcf`: +```ansi +# Убираем единицу из скорборда шагов рейкаста. Когда число достигнет нуля, рейкаст перестанет идти дальше. +scoreboard players remove @s raycast 1 +# Если блок на текущем расположении не является тем, что в теге (группе) namespace:raycast_ignore, то тогда запускается функция столкновения с блоком. +execute unless block ~ ~ ~ namespace:raycast_ignore run function namespace:raycast/hit_block +# Если текущее расположение находится внутри хитбокса любой сущности из тега (группы) namespace:raycast_entities (кроме самого запускателя рейкаста), то запустить функцию столкновения с сущностью. +execute as @e[type=namespace:raycast_entities,dx=0,limit=1] positioned ~-0.99 ~-0.99 ~-0.99 if entity @s[dx=0] run function namespace:raycast/hit_entity +# Здесь можно писать ещё команды, которые будут запускаться на каждом шагу луча. Для примера заспавним партикл: +particle composter ~ ~ ~ 0 0 0 0 1 +# Если скорборд шагов рейкаста равен 1 или больше, то передвинуться немного вперёд и запустить эту же функцию снова. +execute if score @s raycast matches 1.. positioned ^ ^ ^0.1 run function namespace:raycast/ray +``` +4. В функциях `raycast/hit_block` и `raycast/hit_entity` обязательно нужно написать команду обнуления скорборда шагов рейкаста, а дальше можно писать команды, которые будут запускаться при столкновении с блоком и сущностью соответственно: +{mcf}`raycast/hit_block.mcf`: +```ansi +scoreboard players set @a[tag=raycaster] raycast 0 +# Дальше свои команды... Например спавн молнии: +summon lightning_bolt ~ ~ ~ +``` +{mcf}`raycast/hit_entity.mcf`: +```ansi +scoreboard players set @a[tag=raycaster] raycast 0 +# Дальше свои команды... Например нанесение урона: +damage @s 5 +``` +---separator--- +5. Создадим те самые теги (группы) блоков, через которые рейкаст может проходить спокойно, и сущностей, с которыми рейкаст будет сталкиваться. +{tags_file}`tags/block/raycast_ignore.json`: +```json +{ + "values": [ + "#air", + "structure_void", + "light" + ] +} +``` +{tags_file}`tags/entity_type/raycast_entities.json`: +```json +{ + "values": [ + "player", + "pig", + "husk" + ] +} +``` +6. Не забывайте, что вы можете упрощать этот пример под вас! Если вам не надо две разные функции для столкновения с блоком и сущностью, создайте одну, например `hit.mcf`, если вам вообще не надо запускать команды при столкновении с блоком/сущностью, то вообще не создавайте те функции а просто обнуляйте скорборд шагов рейкаста, если вам не надо чекать какие то определённые группы сущностей, можете не создавать теги из 4 пункта, и т. д. \ No newline at end of file diff --git a/assets/links.json b/assets/links.json index 443dbe9..d5e8c2d 100644 --- a/assets/links.json +++ b/assets/links.json @@ -7,6 +7,7 @@ "https://github.com/Dominexis/Atlas-Logger": ["Atlas logger","федфы дщппук","атлас логгер"], "https://github.com/DartCat25/CEM-S": ["DartCat25's CEM-S","cems","цемс","суьы"], "http://www.javadecompilers.com/": ["Java Decompilers online","jdo","джава декмопайлер","джава декомпилятор","fernflower","javadecompilers","офмф вусщьзшдук","фэрнфлауэр","javadecomp"], + "https://java-decompiler.github.io/": ["Java Decompilers GUI","jdg","джава декмопайлер гуи","джава декомпилятор гуи","джг"], "https://mcstacker.net/": ["mcstacker.net","mcstacker","mcs","command generator","cmd gen","мсстакер","мцстакер","генераторы команд","кмд ген","ьсыефслук.туе","ьсыефслук","ьсы"], "https://github.com/Triton365/BlockState": ["BlockState","get states","block to nbt converter","bst","блокстейт","получить блокстейты","идщслыефеу"], "https://modrinth.com/datapack/player_motion": ["Player Motion","Delta new","pm","Моушн игрока","игрока моушн","плеер моушн","новая дельта","пм","Здфнук Ьщешщт","зь"], diff --git a/cogs/faqs/faqs.json b/cogs/faqs/faqs.json index 23031e3..9e9e9f9 100644 --- a/cogs/faqs/faqs.json +++ b/cogs/faqs/faqs.json @@ -47,5 +47,6 @@ "interaction сущность": ["interaction","interaction entity","интеракшн","интеракшн сущность","сущность интеракшн","интеракция","сущность интеракция","интеракция сущность","пкм детект интеракшн","пкм детект интеракция","лкм пкм детект сущность","entity interaction", "right left click detection entity","сущность взаимодействия","взаимодействие сущность","интерактивная сущность"], "item_model": ["айтем модел","айтем модел компонент","компонент айтем модел","item model","item model component","компонент модели предмета","модель предмета компонент","component item model"], "все селекторы": ["all selectors","все селекторы","селекторы","селекторы все","селекторы всех","селекторы всех типов","селекторы типов","селекторы аргументов","все аргументы селекторов","все аргументы","аргументы селекторов","аргументы","arguments","arguments selectors","arguments all","arguments all selectors","arguments selectors all","arguments selectors types","arguments types selectors","arguments types","types arguments","types","types selectors","selectors types","selectors","selectors all","selectors all types"], - "lang": ["language","lang","язык","язык рп","lang resourcepacks","язык в ресурспаках","ланг в ресурспаке","ланг","как работать с лангом"] + "lang": ["language","lang","язык","язык рп","lang resourcepacks","язык в ресурспаках","ланг в ресурспаке","ланг","как работать с лангом"], + "рейкаст": ["raycast","рейкастинг","рк","ray"] }