Когда есть только скрипт, или же карта, которую не открыть в карте, вызов через консоль становится актуальным.
Такая информация предназначена для пользователей уровня выше начинающего. Таким лучше смотреть оригинальное руководство. Данный же перевод сосредоточен на синтаксисе. PT153:
Поправь оглавление, два раза статья 1.
Это не ошибка, это исправление.
Дело в том, что сайт не позволяет редактировать собственную статью напрямую, каждая правка требует проверки модератором. Другими словами, я внес изменения в главу 1 но никто их не подтвердил, поэтому висит 2 первых главы.
На самом деле я внёс довольно много исправлений вскоре после публикации (модератором). Правки были отклонены а сама статья снята с публикации (другим модератором). Почему она тут снова висит (при этом без внесённых тогда правок) я не знаю.
PyCCKuu_4eJl, в идеале лучше по максимуму избегать нативных и бж-функций, заменяя их эквивалентамии из стандартной библиотеки, например
код
package Test
import NoWurst
import Trigger
import RegisterEvents
function actions()
// ...
init
CreateTrigger() // Тут ничего не поделаешь, берем нативную
..registerAnyUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT)
..addCondition( Condition(()->GetSpellAbilityId() == 'A000') )
..addAction(function actions) // Из пакета Trigger
registerSpellEffectEvent('A000', function actions) // То же самое, но короче (пакет RegisterEvents)
Есть новые патчи, но там (могу ошибаться) не получить бонусную (зелёную) атаку.
Есть мемхак, в котором никто не разбирается. Самая непопулярная вещь на данный момент.
Можно построить базу данных. В качестве упрощения, бд можно не выносить из РО, а вместо этого вбивать нужные значения предметов/способностей/юнитов в поле их имени, которое отображается только в редакторе, по принципу ключ-значение и уже в игре получать эти данные через GetObjectName. Ну это так, к слову.
Есть два типа баффов - периодический (максимальное количество тиков больше 1) и непериодический.
Не проще было бы задавать бафф просто длительностью и интервалом между периодическим эффектом? В 6 секунд длительностью и 1.5 секундным интервалом срабатывает 4 раза. Вроде на порядок проще получается.
Не решает. Ты должен думать о реализации своего алгоритма, а не о внутреннем устройстве движка игры. Насколько сильно ты можешь сократить количество команд и операций для решения поставленной задачи.
Хэш-таблица и массивы, это не альтернатива друг другу. На практике они используются совместно.
Каждая сторона треугольника рассматривается как отрезок, лежащий на прямой. Для каждого из этих отрезков строится уравнение прямой.
Уравнение прямой:
Ax + By + C = 0
Отрезки заданы двумя точками - вершинами треугольника - соответственно уравнение прямой для каждой стороны треугольника будет выглядеть следующим образом:
x1, y1 - первая точка отрезка
x2, y2 - вторая точка отрезка
x, y - точка, нахождение которой внутри треугольника проверяется
Строишь такое уравнение для каждой стороны треугольника и высчитываешь их значения
result1 - для первой стороны
result2 - для второй стороны
result3 - для третей стороны
Проверка принадлежности будет следующая - если результаты вычисления для всех сторон треугольника имеют один и тот же знак, значит точка лежит внутри треугольника, если хотя бы один из результатов равен нулю, значит точка лежит на прямой, на которой лежит сторона треугольника, следовательно знак не имеет значения. Записать это можно так:
return (result1 <= 0 and result2 <= 0 and result3 <= 0) or (result1 >= 0 and result2 >= 0 and result3 >= 0)
Замечу, что данный метод подходит для треугольника, четырехугольника и любого выпуклого многоугольника, а так же полигональных фигур, собранных из треугольников/четырехугольников.
Ссылки других комментаторов не проверял, скорее всего там представлено именно это решение.
C++ не изменяет синтакцис объявления блоков кода, переменных, функций. Он не изменяет синтаксис языка кардинально, но дополняет его, поэтому он не делает его хуже.
cJass - полная противоположность vJass, не имеющая с ним ничего общего, при этом допускающая свое смешение. Это делает его хуже. Очень сильно хуже.
Глава собиралась из кусков как гайдов прошлого, так и не столь давних новостей в блоге Wurst, посему ее не могло быть на момент написание прочих глав более года назад.
Юзайте Location, оно как раз для этого было введено.
Что не отличается от неудобств использования вектора. Как уже сказал Doc, не все функции принимают Location. Более того, использовать его нисколько не удобно, из-за необходимости вызова сторонней функции для получения хранящихся в нём данных и хуже всего, это хэндл, который надо уничтожать (подобно векторам) и обнулять. Clamp:
Никто здесь не делал претензий на то, что пишет свой язык, (вурст говно кстати в плане удобства синтаксиса).
Это вкусавщина. Тебе удобно упираться в фигурные скобки и писанину function/takes/returns/endfunction, а кому-то нужна краткость и объективность.
Что отрицать не получится, что Wurst - единственный полноценный компилятор не брошенный разработчиком, с самым широким спектром возможностей супротив его предшественникам.
Практически применял эту библиотеку, что я делал не так?
Подразумевалось повседневное использование, скажем, вместо глобалок X/Y для координат юнита. Сейчас это не актуально из-за необходимости вызывать конструктор/деструктор и невозможности передать стандартным функциям вектор напрямую. Писанины становится слишком много ради простой пары координат. Clamp:
Doc, ещё для =, >, < и ==.
Только для < и == > и != генерируются автоматически на основе их обратных эквивалентов.
Такие темы могут быть интересны для общей информации.
Для практического применения такие библиотеки должны дополнять стандартный функционал редактора. Wurst, например, в стандартной библиотеке тоже содержит типы vec2 и vec3, но в добавок он расширяет стандартные типы для их использования. Например, все функции устанавливающие координаты тем или иным объектам принимают в качестве параметров именно vec2 и vec3, в чем и раскрывается их мощь. А для старого vJass, это да, это по большому счету, простите, пердёж в подушку. PrincePhoenix:
Но! Такие треды, в первую очередь, помогают тем, кто хочет развиться дальше варкрафта и уйти в геймдев.
Одно другому не мешает. WC3 как конструктор лего, больше развлечение чем работа. Жвачка для мозгов, может быть.
Заботься о чистоте когда. Любой скриптовой язык пишется для удобства программиста, производительность это не главная вещь, о которой в нем нужно задумываться.
Что за visual code? Чтобы тестирование не запускалось в оконном режиме, убери отсюда галку:
Visual Studio Code
Wurst работает с кодом карты и РО из внешнего текстового редактора, на WE остается переключаться разве что ради ландшафта. Это к тому, что JNGP или SharpCraft с Wurst используются не часто.
ScopteRectuS, в программировании сравнивать действительные числа не принято, это в большинстве случаев дает неверный результат из-за потери точности и принципа хранения данных.
Как заметил UrsaBoss, есть функция R2SW, чья максимальная точность - 9 знаков, но даже в этом случае будет иметь место округление.
В целом Clamp, говорит верно, такие потребности не должны возникать в логике программы, поскольку типы с плавающей запятой ненадежны, они с потерями.
Если нужно совсем прям совсем, можно использовать vJass/ZINC/Wurst и объявить структуру (в случае Wurst - класс) который будет содержать в поле данные типа real. Что-то вроде
Код
struct Float
private real value
static method create takes real newValue returns Float
local Float this = Float.allocate()
set value = newValue
return this
endmethod
method getValue takes nothing returns real
return value
endmethod
method setValue takes real newValue returns nothing
set value = newValue
endmethod
endstruct
Тогда каждый экземпляр структуры будет обладать уникальным целочисленным значением в диапазоне от 1 до 8190 (или больше, если в патче 1.28+), эдакая ссылочная обертка для примитивного типа.
Слишком много вражеских юнитов, среди атак которых не разобрать, где способности. Демонстрацию нужно разделить на несколько этапов, где способности тестируются на пассивных противниках. Уже после можно озадачиться рубиловом.
Ах, я понял чего ты хочешь конкретно сейчас. Чтобы модель смотрела в камеру, словно на экране выбора персонажа? В таком случае ситуация немного упрощается.
Нам больше не нужно хранить текущую матрицу поворота эффекта, ведь мы не производим ее вращение, вместо этого мы высчитывает всю необходимую ориентацию из положения камеры и самого эффекта. Подход, в целом, остается прежним, но для поиска осей ориентации мы теперь будем использовать некоторый вспомогательный вектор, чье направление совпадает с направлением глобальной оси Z, и путем векторного произведения этого вспомогательного вектора на вектор оси X эффекта (получаемый как и прежде p2 - p1) мы получаем вектор ориентации эффекта Y, а векторное произведение X на Y нам даст ось Z эффекта.
Весь процесс можно разжевать на множество абзацев, но делать этого нет смысла. Я проще скину твою карту с новым вариантом.
Тем не менее, я вижу некоторое непонимание темы и потому считаю должным указать на некоторые ошибки в твоем прошлом коде
Код
private function RotationMatrixToEuler takes MATRIX3 R returns VECTOR3
local real x
local real y
local real z
local real sy = SquareRoot(R.m11 * R.m11 + R.m21 * R.m21)
local boolean singular = sy < .000001 or sy == 0 // If
if not singular then
set x = Atan2(R.m32 , R.m33)
set y = Atan2(-R.m31, sy)
set z = Atan2(R.m21, R.m11)
else
set x = Atan2(-R.m23, R.m22)
set y = Atan2(-R.m31, sy)
set z = 0
endif
return VECTOR3.New_1(x, y, z)
endfunction
Я не понимаю, как работает эта функция. В моем понимании, преобразование матрицы поворота в углы Эйлера происходит за счет обратного преобразования. То есть, чтобы преобразовать матрицу в Эйлер, необходимо знать как преобразуется Эйлер в матрицу, поскольку это обратные друг другу процессы. В новом примере я ее переписал.
Код
set rotation.m11 = X.x
set rotation.m12 = X.y
set rotation.m13 = X.z
set rotation.m21 = Y.x
set rotation.m22 = Y.y
set rotation.m23 = Y.z
set rotation.m31 = Z.x
set rotation.m32 = Z.y
set rotation.m33 = Z.z
Здесь идет неверное назначение параметров матрицы. Дело в том, что матрица записывается следующим образом (из readme библиотеки Math)
m11 m12 m13
m21 m22 m23
m31 m32 m33
При этом, оси записываются слева направо, столбиками, то есть , ось X здесь, это m11, m21 и m31. Следовательно верной записью будет
Код
set rotation.m11 = X.x
set rotation.m21 = X.y
set rotation.m31 = X.z
set rotation.m12 = Y.x
set rotation.m22 = Y.y
set rotation.m32 = Y.z
set rotation.m13 = Z.x
set rotation.m23 = Z.y
set rotation.m33 = Z.z
И самая ложная строка
set rotation = MATRIX3.New_0()
Это создаст нулевую матрицу, то есть матрицу, все значения которой - нули. Базовая же матрица поворота, это единичная матрица, то есть матрица, чья главная диагональ состоит из единиц, а все остальное - нули.
Но это просто заметки, в текущей версии этих участков кода больше нет.
Ред. GetLocalPlayer
» WarCraft 3 / Wurst
Ред. GetLocalPlayer
» WarCraft 3 / vJass
PT153:
Дело в том, что сайт не позволяет редактировать собственную статью напрямую, каждая правка требует проверки модератором. Другими словами, я внес изменения в главу 1 но никто их не подтвердил, поэтому висит 2 первых главы.
На самом деле я внёс довольно много исправлений вскоре после публикации (модератором). Правки были отклонены а сама статья снята с публикации (другим модератором). Почему она тут снова висит (при этом без внесённых тогда правок) я не знаю.
Ред. GetLocalPlayer
» WarCraft 3 / Странный Wurst
» WarCraft 3 / Странный Wurst
» WarCraft 3 / Странный Wurst
darkowlom:
» WarCraft 3 / Как узнать кол-во единиц атаки у юнита?
» WarCraft 3 / Как узнать кол-во единиц атаки у юнита?
» WarCraft 3 / Триггерный бафф
Ред. GetLocalPlayer
» WarCraft 3 / Хеш-таблица или куча массивных переменных
Ред. GetLocalPlayer
» WarCraft 3 / Область с формой треугольника
Уравнение прямой:
» Clamp'ова кухня / Векторы
cJass - полная противоположность vJass, не имеющая с ним ничего общего, при этом допускающая свое смешение. Это делает его хуже. Очень сильно хуже.
» WarCraft 3 / 14. Аннотации
» Clamp'ова кухня / Векторы
Ред. GetLocalPlayer
» Clamp'ова кухня / Векторы
Ред. GetLocalPlayer
» Clamp'ова кухня / Векторы
Clamp:
Clamp:
Что отрицать не получится, что Wurst - единственный полноценный компилятор не брошенный разработчиком, с самым широким спектром возможностей супротив его предшественникам.
» Clamp'ова кухня / Векторы
Clamp:
> и != генерируются автоматически на основе их обратных эквивалентов.
» Clamp'ова кухня / Векторы
PrincePhoenix:
» Clamp'ова кухня / Векторы
Ред. GetLocalPlayer
» WarCraft 3 / Wurst script
Ред. GetLocalPlayer
» WarCraft 3 / Wurst script
- Никогда, честно говоря, не задумывался.
- Заботься о чистоте когда. Любой скриптовой язык пишется для удобства программиста, производительность это не главная вещь, о которой в нем нужно задумываться.
8gabriel8:Wurst работает с кодом карты и РО из внешнего текстового редактора, на WE остается переключаться разве что ради ландшафта. Это к тому, что JNGP или SharpCraft с Wurst используются не часто.
» WarCraft 3 / GetRealId( )
» WarCraft 3 / GetRealId( )
В целом Clamp, говорит верно, такие потребности не должны возникать в логике программы, поскольку типы с плавающей запятой ненадежны, они с потерями.
Если нужно совсем прям совсем, можно использовать vJass/ZINC/Wurst и объявить структуру (в случае Wurst - класс) который будет содержать в поле данные типа real. Что-то вроде
Ред. GetLocalPlayer
» WarCraft 3 / GetRealId( )
» WarCraft 3 / Кел'Тузад из Heroes of the Storm
Ред. GetLocalPlayer
» WarCraft 3 / Ориентация эффекта в пространстве
Нам больше не нужно хранить текущую матрицу поворота эффекта, ведь мы не производим ее вращение, вместо этого мы высчитывает всю необходимую ориентацию из положения камеры и самого эффекта. Подход, в целом, остается прежним, но для поиска осей ориентации мы теперь будем использовать некоторый вспомогательный вектор, чье направление совпадает с направлением глобальной оси Z, и путем векторного произведения этого вспомогательного вектора на вектор оси X эффекта (получаемый как и прежде p2 - p1) мы получаем вектор ориентации эффекта Y, а векторное произведение X на Y нам даст ось Z эффекта.