WarCraft 3: Исследование порчи (Blight)

» Раздел: Триггеры и объекты
» Автор оригинала: Romeno

Делал тригерный спел с эффектом наведения порчи и... решил разобраться как она работает.
Казалось бы всё просто координаты, размер региона и готово. И тем не менее выкладываю результат сего изыска...

Основы

В первую очередь нужно сказать, что наведение порчи в WE отличается от наведения порчи с помощью скриптов.
Наводить порчу на землю можно или в WE или в игре с помощью
» Blight API
native SetBlight takes player whichPlayer, real x, real y, real radius, boolean addBlight returns nothing
native SetBlightRect takes player whichPlayer, rect r, boolean addBlight returns nothing
native SetBlightPoint takes player whichPlayer, real x, real y, boolean addBlight returns nothing
native SetBlightLoc takes player whichPlayer, location whichLocation, real radius, boolean addBlight returns nothing
native IsPointBlighted takes real x, real y returns boolean
» Триггерных действий
Как и в WE порча привязана к сетке. SetBlightPoint создаёт никакой не point, а регион размером 512 на 512.
Минимальный радиус региона наведённого с помощью SetBlight - 128. Значения меньшие 128 округляются до 128. Следующие радиусы кратны 128. При указании не кратного радиус округляется к ближайшему кратному, т.е. 150 к 128, 192 к 256 и т.д.
Визуально минимальный порченый регион выглядит меньше,
» чем есть на самом деле
Круговые регионы порчи - достаточно
Здесь любопытный момент в том, что мелкие квадратики имеют сторону 128, а не 256. Значит минимальный радиус таки 64, а не 128, об этом ниже.
В WE они ещё более квадратные:
» без маленьких скругляющих квадратиков + размер "кистей" другой
Центр порченного региона, создаваемового с помощью SetBlight или SetBlightRect привязан к сетке. Квадрат сетки размером 256 на 256. Поэтому, если указать центром, скажем, (2200, 450), то регион будет создан с центром в (2176,512)
Параметр whichPlayer определяет собственника порчи. Учитывая, что порча снимается диспелом по местности, собственник порчи свою порчу снять не сможет. (Thanks to DioD)

Невидимая порча

После того как стало ясно, что минимальный размер квадратика с порчей 128 на 128, я решил поэкспериментировать и посмотреть что будет, если обрезать в-кавычках-минимальный регион 256/256 с помощью мелких квадратиков. Т.е. сначала создал круговую порчу радиуса 256, а затем удалил порчу тоже радиуса 256, сместив центр как
В итоге местность перестала отображаться порченной, но по факту порча на ней частично осталась (красная на рисунке). Типа не видимая порча.
Наверное это можно как-то использовать.
» Также т.о. можно создать порченный регион размера 256 на 384
Удаление кругового региона порчи радиуса 384 (может и не только для него) работает бажно. Верхняя часть региона не удаляется, оставляя небольшой клочок порчи.
SetBlightPoint тоже работает и странно, и бажно. При создании порчи создаётся регион 512 на 512. Центр расположен как показано
Как видно из рисунка "нарисованная" порча, смещена вверх и вправо на 128 от реальной (ахтунг!).
SetBlightRect также
» криво отображает порчу
При размерах региона меньше 65 не создаёт порчу. При размере больше, создаёт прямоугольный регион порчи размером равным ближайшему числу кратному 128. У меня не получилось добиться того, чтобы SetBlightRect нормально отображала наведённую порчу. Так что, наверное, её не стоит использовать.

Заключение

Имхо самое полезное из всего этого, это то что минимальный регион, который можно "испортить" это таки 128 на 128 (для круга) он и отображается не смещённо. Порча такого размера будет видна, если будет граничить с порченным регионом 256 на 256. Если такого региона не будет, то порченным он будет, но отображаться как таковой - нет.
В целом порча работает не очевидно, а кое-где и бажно.
Тестировалось с помощью IsPointBlighted.

Просмотров: 5 290

» Лучшие комментарии


Insenne #1 - 5 лет назад 1
Я бы не сказал что статья бесполезная, но почти ненужная. Это просто слоупок(короче объясняюсь), или как первое документальное дело:)
Vampir1991 #2 - 5 лет назад 0
Insenne, при размере карты 512 на 512 порча только в определенном легионе работает. В каком смысле работает, на ней нельзя строить здания нежити.
Поверь порча гадкая. -_-
Romeno #3 - 5 лет назад 0
Vampir1991, при размере карты 512 на 512 порча только в определенном легионе работает
Заинтересовало, т.е. на картах 512 на 512 в опред. регионе порча отображается, но на самом деле земля не порченная?
Vampir1991 #4 - 5 лет назад 0
Угу.
Darklight #5 - 5 лет назад 0
Интересная и даже полезная статья. Уже сталкивался с проблемой точного наведения порчи.
Но хотелось бы получить чуть больше, а именно:
  1. У меня давно есть вопрос - как наводить порчу на отдельное дерево - например когда Гуль нежити трогает дерево - оно портится. Нужен такой же эффект. Как его достичь тригерно?
  2. Хотелось бы скорректированный API - заменяющий (и расширяющий) стандартный максимально снижающий баг-эффекты.
  3. Хотелось бы больше функций (в новом API) для проверки регионов на предмет порчи, и, наверное, стоит разделить функции на добавляющие порчу и убирающие порчу (и на проверяющие наличие порчи).
Прошу воспринимать мои просьбы не как выклянчивание готовых решений или наезд на неполную статью, а как повод к возможному продолжению данной статьи. И автору спасибо за статью.
Romeno #6 - 5 лет назад (отредактировано ) 0
У меня давно есть вопрос - как наводить порчу на отдельное дерево - например когда Гуль нежити трогает дерево - оно портится. Нужен такой же эффект. Как его достичь тригерно?
Точечно порча не наводится, как я и писал, только мин размер 128 на 128. Поэтому как ты и написал тригерно: создать гуля, ударить по дереву удалить гуля, восстановить здоровье дереву :)
Хотелось бы скорректированный API - заменяющий (и расширяющий) стандартный максимально снижающий баг-эффекты.
Я думал о том, чтобы написать пару тройку функций для создания региона на 128 на 128 и т.п. Но там такая мудистика... Рисовать мелкие квадратики можно только, минимум, порчей радиусом 256, а значит рисование/стирание будет портить рисунок порчи вокруг. Я честно говоря вообще сомневаюьс что это можно сделать номально, с существующим API. А если и можно придётся всю карту порчи перерисовывать начиная с нижнего угла наверное....
Darklight #7 - 5 лет назад 0
Romeno, я думаю, что порча дерева это не точечное наведение порчи (я как раз так пытался - полна лажа), тут что-то хитрее происходит, но что - вот вопрос. Конечно можно и с Гулем попробовать, но он одним махом может снести дерево (если у него мало жизней), что уже сложнее восстановить. Да и не очень верится, что порча дерева Гулем - это встроенная в игру "заплатка" и только он может это делать.
А насчёт API - я всё же предлагаю подумать, никто же не говорит об идеальном решении - но что-нибудь интересное-то придумать можно, раз есть такое нетривиальное исполнение native функций. Типа - хорошая задачка для ума, сообразительности и умения правильно строить алгоритмы ;)
Clamp #8 - 5 лет назад 1
Самая используемая функция редактора - создать порчу, джва года ждал статью.
Steal nerves #9 - 5 лет назад (отредактировано ) 0
автор тебе респект. Но все же стоило бы нарисовать наработку, где порча просто распространяется скажем от здания, или наоборот. Вот это интересно было осмотреть как это реализовано. Вообще можно сделать многоуровневую абилку, распространяющую порчу. С почвой я не работал ни разу триггерно. Там кажись функция есть, где радиус меняешь остепенно меняешь.
Darklight #10 - 5 лет назад 0
Steal nerves, Интересно, что ты в этих уровнях разместить хочешь?
Steal nerves #11 - 5 лет назад (отредактировано ) 1
Darklight, это я так к слову ляпнул. радиусы распространения порчи. Но твоя идея наводить порчу на отдельные декорации - тоже интересная идея.
В одном проекте Necris уже используется подобная идея. От здании со временем распространяется порча по всей карте. Нежити на порченной земле гораздо сильнее, и чтобы этого не допустить возможно в карте сделаем предметы, вызывающие варды. Короче смысл этих вардов остановить и не допустить распространение порчи. Мне показалось это знакомым))
Darklight #12 - 5 лет назад 1
Steal nerves, используй функцию native SetBlight takes player whichPlayer, real x, real y, real radius, boolean addBlight returns nothing для постепенного расширения радиусов.
Как написано в статье - она работает более менее хорошо, особенно для больших радиусов. Использовать абилку статического наведения порчи, учитывая желания иметь варды (интересно, что за слово такое), снимающие порчу, не рекомендую, т.к. порча от этих абилок (на юнитах) не рассеивается, пока действуют эти абилки.
С другой стороны, у вас, явно должно быть посложнее - а именно, если рассеяние порчи сильно и неравномерно углубилось в распространённую порчу, то должен быть восстановлен не весь текущий радиус порчи, а постепенно порча должна как бы затягиваться изнутри к внешней границе.
Верно и обратное - если здание, распространившее порчу уничтожено - то порча должна постепенно уменьшаться в радиусе распространения (как у Зергов в SC).
Поэтому я написал выше, о том, что неплохо бы иметь более расширенную библиотеку по работе с порчей, раз автор затронул эту тему.
Steal nerves #13 - 5 лет назад 0
Darklight, думаю ты прав. У нас посложнее, распространять это самое легкое. Если сделать защиту от порчи (варды), самое сложное, придеться делать по-другому. А очень то хочется иметь в этой карте. Можно было бы сделать, чтобы заранее порчу не наносить, если этот участок находится под защитой, просто с заранее заданной проверкой. Мне кажется через распространения через радиус плохая идея, так как ты порчу распространяешь в округе, а этот круг постепенно разрастает. Для защиты от порчи это плохо, вернее глупо, во-первых происходит смена текстур почвы, была трава, затем порча, потом обратно в песок (если использовать способность здании от порчи), удаляются декорации травы (у нас там еще декор), а еще портятся деревья, и обратно это восстановить вряд ли вообще можно. Надо сделать так, чтобы дальше не шло, просто не трогало этот участок. Надо как-то отсчитать заранее, какой другой функции распространять на отдельные участки, то есть опять логически придумывать, не исключено, что там может быть математические знания. Тут больше вопросов.
Наблюдается несколько моментов:
  1. Что будет если я поставлю вард туда, где находится сама порча, скажем поставим посередине? Может решится эта проблема, тем что ставить на участок порчи и не будет можно.
  2. Я поставил вард. Допустим он действует с определенным радиусом, там где порча действовать не будет. Действуешь в определенной области, а это значит что со временем порча может и не тронет эту область, но уйдет дальше за эту область. Исключить такой вариант тоже надо. Вот если поставить на краю области, где порча находится, то по идее дальше не должно распространяться. К примеру я снизу поставил, и вард действует в строго определенной области, то есть в этой нижней части области порча уже не идет дальше и все.
  3. Еще я был хотел визуально видеть с каким радиусом действует этот вард, чтобы поставить еще один такой же скажем рядышком. Может быть эффектами? Пока это все самое интересное.
Darklight #14 - 5 лет назад 0
Steal nerves, О да, действительно всё сложно. И тут даже уже дело не кривых функциях стандартного Blight API (с некоторой погрешностью им всё же можно пользоваться, наводя поручу "точечно" небольшими радиусами и оптимизируя на больших площадях непрерывной порчи) и, даже не в сложности математического аппарата (да не простой, но всё же это лишь 2D плоскость - геометрия здесь не шибко сложная - можно всё просчитать), а сложность в том, что для такой схемы, как у вас, требуется достаточно гибкая система хранения параметров порчи (хранить её только на карте уже будет недостаточно). ИМХО тут без подключения своих native функций уже будет очень сложно обойтись. А в этих native придётся строить свои структуры хранения (лучше в виде матриц или графических канвасов) и размещать ресурсоёмкие расчеты порчи. Как-то так.
Romeno #15 - 5 лет назад (отредактировано ) 0
Steal nerves, идея интересная, и даже очень, если всё делать триггерно, то варды реализовать можно. Это даже не сложно. Просто в триггер, который будет наводить триггерно порчу от зданий, нужно вставить код, который будет в конце эту порчу снимать с определённого участка, вокруг варда. Также, чтобы порча не заходила за варды, можно в коде делать проверки какие потребуется. Я думаю это реализуемо, больших математический знаний не надо, достаточно посидеть/полежать и подумать. Если очень хочется сохранить текстуру земли, то думаю, можно сохранять тип текстуры и затем опять же в конце этого триггера восстанавливать текстуру земли. Я думаю это не будет сильно напряжно по производительности, т.к. делать это можно, скажем раз в 2 или 5 секунд.
На счёт, того чтобы порча не заходила за варды.. Ну тут не совсем понятно, как таки у тебя они должны работать. Если вард препятствует распространению порчи в некотором конусе от центра её распространения или просто защищает некоторую круговую область. Или 1 вард стопает всю порчу распространяемую из некоторой точки за него по перпендикулярной прямой? Всё это, в любом случае, реализуемо.
На счёт радиуса, мне лично, больше всего нравится как радиусы показаны у башен в YouTD. Там на кнопку у башни нажимаешь, и они рунами отображаются, а через некоторое время исчезают.
На счёт восстановления деревьев... Да... видимо это проблема... Протестил:
    call SetBlight(Player(0), 0, 0, 10000, true)
    call SetBlight(Player(0), 0, 0, 10000, false)
Делает все деревья порченными. НО! При этом текстуры земли НЕ меняются! :) Ахтунг. Ещё 1. Вот способ "испортить" все деревья в регионе, не меняя текстуру земли.
На счёт декораций.. Неужели порча ещё и убивает какие-то декорации??
И да, Steal nerves, про многоуровневую абилку, наводящую порчу. Она таки есть у меня в Warcraft 3: In the Shadows у Болотного Монстра. Наводит порчу, постепенно расширяясь со временем, в течение нескольких секунд.
Darklight, С другой стороны, у вас, явно должно быть посложнее - а именно, если рассеяние порчи сильно и неравномерно углубилось в распространённую порчу, то должен быть восстановлен не весь текущий радиус порчи, а постепенно порча должна как бы затягиваться изнутри к внешней границе.
Верно и обратное - если здание, распространившее порчу уничтожено - то порча должна постепенно уменьшаться в радиусе распространения (как у Зергов в SC).
Поэтому я написал выше, о том, что неплохо бы иметь более расширенную библиотеку по работе с порчей, раз автор затронул эту тему.
Да.. это ещё одно усложнение этой механики, но это всё - реализуемо. И тут уже, конечно, не просто библиотека, а наработка-система такого поведения зданий.
Вармиръ #16 - 2 года назад 0
обновите скрины
GF RaiseD #17 - 2 года назад 4
Вармиръ, файлы были загружены на файлообменники. Видимо, временно (что не есть хорошо). Автор не появлялся уже пол-года, а кроме него исправлять его статью хотят не только лишь все, мало кто хочет это делать.