15

» WarCraft 3 / Wurst

Принятый ответ
Такое может произойти если функция не объявлена публичной
public function StatsSyncAll(unit owner)
    // Ра-та-та-та-та
По умолчанию, объявления внутри пакета приватные.
P.S. в Wurst лучше придерживаться стиля Wurst. То бишь, имена функций и переменных следует начинать с маленькой буквы
public function  statsSyncAll(unit owner)
15

» WarCraft 3 / vJass

Там была некоторая важная информация, её можно было оставить. В частности, я говорю о спецфлагах в файле jasshelper.conf.
Когда есть только скрипт, или же карта, которую не открыть в карте, вызов через консоль становится актуальным.
Такая информация предназначена для пользователей уровня выше начинающего. Таким лучше смотреть оригинальное руководство. Данный же перевод сосредоточен на синтаксисе.
PT153:
Поправь оглавление, два раза статья 1.
Это не ошибка, это исправление.
Дело в том, что сайт не позволяет редактировать собственную статью напрямую, каждая правка требует проверки модератором. Другими словами, я внес изменения в главу 1 но никто их не подтвердил, поэтому висит 2 первых главы.
На самом деле я внёс довольно много исправлений вскоре после публикации (модератором). Правки были отклонены а сама статья снята с публикации (другим модератором). Почему она тут снова висит (при этом без внесённых тогда правок) я не знаю.
15

» WarCraft 3 / Странный Wurst

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)
15

» WarCraft 3 / Странный Wurst

В Phython табуляция не влияет на компиляцию, потому что Phython - интерпретируемый язык, у него нет компилятора.
Я о компиляции Python* ничего не говорил.
15

» WarCraft 3 / Странный Wurst

Оно прям error выводило? Оно могла просто подчеркнуть, что ты забыл табуляцию.
На уровне модуля компилятор не ждёт табуляции, только объявление, посему воспринимает вызов как попытку объявить переменную
darkowlom:
Впервые вижу такое в языках
Ну хотя бы о Python ты должен был что-нибудь слышать....
15

» WarCraft 3 / Как узнать кол-во единиц атаки у юнита?

это что за графа такая?
Текст - Название, но там тоже не всё гладко. В новом патче попроще, поскольку названия можно еще и менять, избавляясь от ряда ограничений.
15

» WarCraft 3 / Как узнать кол-во единиц атаки у юнита?

  • Есть новые патчи, но там (могу ошибаться) не получить бонусную (зелёную) атаку.
  • Есть мемхак, в котором никто не разбирается. Самая непопулярная вещь на данный момент.
  • Можно построить базу данных. В качестве упрощения, бд можно не выносить из РО, а вместо этого вбивать нужные значения предметов/способностей/юнитов в поле их имени, которое отображается только в редакторе, по принципу ключ-значение и уже в игре получать эти данные через GetObjectName. Ну это так, к слову.
15

» WarCraft 3 / Триггерный бафф

Есть два типа баффов - периодический (максимальное количество тиков больше 1) и непериодический.
Не проще было бы задавать бафф просто длительностью и интервалом между периодическим эффектом? В 6 секунд длительностью и 1.5 секундным интервалом срабатывает 4 раза. Вроде на порядок проще получается.
15

» WarCraft 3 / Хеш-таблица или куча массивных переменных

Быстрота работы ведь тоже решает
Не решает. Ты должен думать о реализации своего алгоритма, а не о внутреннем устройстве движка игры. Насколько сильно ты можешь сократить количество команд и операций для решения поставленной задачи.
Хэш-таблица и массивы, это не альтернатива друг другу. На практике они используются совместно.
15

» WarCraft 3 / Область с формой треугольника

Принятый ответ
Каждая сторона треугольника рассматривается как отрезок, лежащий на прямой. Для каждого из этих отрезков строится уравнение прямой.
Уравнение прямой:
Ax + By + C = 0
Отрезки заданы двумя точками - вершинами треугольника - соответственно уравнение прямой для каждой стороны треугольника будет выглядеть следующим образом:
(y1 - y2) * x + (x2 - x1) * y + (x1 * y2 - x2 * y1) = 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)
Замечу, что данный метод подходит для треугольника, четырехугольника и любого выпуклого многоугольника, а так же полигональных фигур, собранных из треугольников/четырехугольников.
Ссылки других комментаторов не проверял, скорее всего там представлено именно это решение.
15

» Clamp'ова кухня / Векторы

C++ не изменяет синтакцис объявления блоков кода, переменных, функций. Он не изменяет синтаксис языка кардинально, но дополняет его, поэтому он не делает его хуже.
cJass - полная противоположность vJass, не имеющая с ним ничего общего, при этом допускающая свое смешение. Это делает его хуже. Очень сильно хуже.
15

» WarCraft 3 / 14. Аннотации

Глава собиралась из кусков как гайдов прошлого, так и не столь давних новостей в блоге Wurst, посему ее не могло быть на момент написание прочих глав более года назад.
15

» Clamp'ова кухня / Векторы

Что делает его только хуже. Например, когда появляются вопросы с нечитабельной мешаниной из vJass и cJass.
15

» Clamp'ова кухня / Векторы

А что, они при этом не перегружаются? К чему это уточнение?
Doc, уже ответил, контроля нет.
Clamp:
Юзайте Location, оно как раз для этого было введено.
Что не отличается от неудобств использования вектора. Как уже сказал Doc, не все функции принимают Location. Более того, использовать его нисколько не удобно, из-за необходимости вызова сторонней функции для получения хранящихся в нём данных и хуже всего, это хэндл, который надо уничтожать (подобно векторам) и обнулять.
Clamp:
Никто здесь не делал претензий на то, что пишет свой язык, (вурст говно кстати в плане удобства синтаксиса).
Это вкусавщина. Тебе удобно упираться в фигурные скобки и писанину function/takes/returns/endfunction, а кому-то нужна краткость и объективность.
Что отрицать не получится, что Wurst - единственный полноценный компилятор не брошенный разработчиком, с самым широким спектром возможностей супротив его предшественникам.
15

» Clamp'ова кухня / Векторы

Практически применял эту библиотеку, что я делал не так?
Подразумевалось повседневное использование, скажем, вместо глобалок X/Y для координат юнита. Сейчас это не актуально из-за необходимости вызывать конструктор/деструктор и невозможности передать стандартным функциям вектор напрямую. Писанины становится слишком много ради простой пары координат.
Clamp:
Doc, ещё для =, >, < и ==.
Только для < и ==
> и != генерируются автоматически на основе их обратных эквивалентов.
15

» Clamp'ова кухня / Векторы

не вижу ни одного юзкейса
Такие темы могут быть интересны для общей информации.
Для практического применения такие библиотеки должны дополнять стандартный функционал редактора. Wurst, например, в стандартной библиотеке тоже содержит типы vec2 и vec3, но в добавок он расширяет стандартные типы для их использования. Например, все функции устанавливающие координаты тем или иным объектам принимают в качестве параметров именно vec2 и vec3, в чем и раскрывается их мощь. А для старого vJass, это да, это по большому счету, простите, пердёж в подушку.
PrincePhoenix:
Но! Такие треды, в первую очередь, помогают тем, кто хочет развиться дальше варкрафта и уйти в геймдев.
Одно другому не мешает. WC3 как конструктор лего, больше развлечение чем работа. Жвачка для мозгов, может быть.
15

» Clamp'ова кухня / Векторы

Я бы предложил переименовать конструктор
public static Vec3 createAt(float x, float y, float z)
в
public static Vec3 create(float x, float y, float z)
А в свою очередь обычный
public static Vec3 create() 
в
public static Vec3 createZero() 
И добавить метод
    public string toString() {
        return "Vec3[" + R2S(x) + ", " + R2S(y) + ", "  + R2S(z) + "]";
    }
Аналогично для Vec2
15

» WarCraft 3 / Wurst script

Никогда, честно говоря, не задумывался.
UPD: Задался вопросом на трекере. Пока невозможно.
Загруженные файлы
15

» WarCraft 3 / Wurst script

Принятый ответ
  1. Никогда, честно говоря, не задумывался.
  2. Заботься о чистоте когда. Любой скриптовой язык пишется для удобства программиста, производительность это не главная вещь, о которой в нем нужно задумываться.
8gabriel8:
Что за visual code? Чтобы тестирование не запускалось в оконном режиме, убери отсюда галку:
Visual Studio Code
Wurst работает с кодом карты и РО из внешнего текстового редактора, на WE остается переключаться разве что ради ландшафта. Это к тому, что JNGP или SharpCraft с Wurst используются не часто.
15

» WarCraft 3 / GetRealId( )

ScopteRectuS, в программировании сравнивать действительные числа не принято, это в большинстве случаев дает неверный результат из-за потери точности и принципа хранения данных.
15

» WarCraft 3 / GetRealId( )

GetLocalPlayer, проверил, R2S( ) округляет. R2S( 0.03125 ) > "0.031"
Как заметил 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+), эдакая ссылочная обертка для примитивного типа.
15

» WarCraft 3 / GetRealId( )

Зачем оно тебе надо, не мое дело. Но если надо, можешь преобразовать действительное число в строку и получить хэш этой строки через StringHash.
15

» WarCraft 3 / Кел'Тузад из Heroes of the Storm

Слишком много вражеских юнитов, среди атак которых не разобрать, где способности. Демонстрацию нужно разделить на несколько этапов, где способности тестируются на пассивных противниках. Уже после можно озадачиться рубиловом.
15

» WarCraft 3 / Ориентация эффекта в пространстве

Принятый ответ
Ах, я понял чего ты хочешь конкретно сейчас. Чтобы модель смотрела в камеру, словно на экране выбора персонажа? В таком случае ситуация немного упрощается.
Нам больше не нужно хранить текущую матрицу поворота эффекта, ведь мы не производим ее вращение, вместо этого мы высчитывает всю необходимую ориентацию из положения камеры и самого эффекта. Подход, в целом, остается прежним, но для поиска осей ориентации мы теперь будем использовать некоторый вспомогательный вектор, чье направление совпадает с направлением глобальной оси 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()
Это создаст нулевую матрицу, то есть матрицу, все значения которой - нули. Базовая же матрица поворота, это единичная матрица, то есть матрица, чья главная диагональ состоит из единиц, а все остальное - нули.
Но это просто заметки, в текущей версии этих участков кода больше нет.
Загруженные файлы