Ну а возвращаясь к роликам. Проблема вара в том, что знание, как он работает (точнее, как он работает вопреки здравому смыслу), лежит в головах людей, и это знание из года в год мутирует. Особенно когда речь идёт о багах и эксплоитах. Решение у данной проблемы простое: создание базы тестов, которая проверяет каждое заявление на правдивость.
Автор в своём первом ролике лишь подкидывает мутации и слухи в копилку, не подтверждая свои слова ничем. Поэтому я и написал:
после первого ролика не появилось желание смотреть остальные.
Зачем мне смотреть рентв, оформленное в стиле вара? Да не то что мне, а вообще кому-то.
Самое главное это то, что автор всё-таки признал свои ошибки и в будущем их исправит (наверное). Вот признание собственных ошибок я ценю, а низкокачественный контент, кем бы он не был сделан и что бы он не продвигал, - нет.
Если у тебя есть идея построить дом, а с собой только пила. топор и три болта то ты просто умрёшь от увлекательности проживания в лесном шалаше. А вот если за тобой много строй материалов и целая бригада строителей разница в конечном итоге будет кардинально другая.
Найс аналогии пошли, вот только я напомню, что кампания вк3 полностью на гуи. Увлекательна ли она? Разумеется. Качественна ли она? Безусловно. Так что подобные аналогии идут лесом. В первую очередь нужно продумать геймдизайн, а затем выбирать инструменты, которыми его можно реализовать. Если для этого подходит гуи, то не вижу никакой проблемы.
P.S. Забыл упомянуть, что все наследники интерфейса разделяют одно и то же пространство в 8192 объекта. Тоже не нашёл в руководствах.
На самом деле это следует из того, что наследники вызывают allocate родителя.
Я так понимаю, описание проблемы вот?
Самая большая проблема, которую я на текущий момент вижу, это, во-первых, возможность через индекс обращаться даже к несуществующим/уничтоженным объектам, и, во-вторых, сохранение всех ссылок на экземпляр структуры после её уничтожения (и да, я понимаю, что это не ссылки, а целочисленные индексы).
Решить первую проблему невозможно, как раз из-за того, что любой объект структуры есть целое число. И в любом месте для структуры MyStruct я могу сделать вот так:
call MyStruct(6).my_method()
Что уж говорить, есть возможность точечно менять значение приватного поля определённого объекта.
Второй проблемы в высокоуровневых языках быть не может, просто потому что объект остаётся в памяти до тех пор, пока на него ссылаются. Во время выполнения JASS никак нельзя узнать, сколько переменных ссылаются на то или иное число, дабы отложить вызов метода destroy, не говоря уже о том, что нет никакой информации, какой именно destroy нужно отложить. Поэтому её тоже решить невозможно.
Следствием этой особенности джасса является огромнейший потенциал неведомых ошибок во время исполнения: при параллельном использовании одних и тех же экземпляров структур в разных триггерах триггеры в разное время могут использовать разные объекты, при этом продолжая считать, что обрабатывают первоначально поданный. Ключевым здесь является то, что такая подмена обрабатываемого объекта (указатель на который мог быть сохранен, например, в хэштаблице) не вызовет никаких исключений или ошибок. Исполнение просто продолжится, как будто так и надо. Впрочем, с самого начала было ясно, что в рамках джасса отладка является синонимом страданий. Мне, привычному к структурированной обработки C#, это бывает больно.
Могу предложить вот что. Немного исправленный код из моей карты.
Триггер gg_trg_ErrorOccurred нужен для выполнения кода для каждого игрока в случае ошибки в отдельном потоке операций. Во-первых, это значит, что код внутри Trig_ErrorOccured_Actions не будет учитываться в лимит операций того кода, что вызвал ErrorOccurred, а во-вторых, если какой-то код внутри Trig_ErrorOccured_Actions рушит поток (например, вызов EndThread), выполнение TriggerExecute завершится, и начнётся выполнение FinishGameNoCheck.
Впрочем, можно оставить только Trig_ErrorOccured_Actions и вызвать её через .execute(), vJass сам сделает для неё триггер.
function Trig_ErrorOccured_Actions takes nothing returns nothing
local integer i = 0
loop
exitwhen i > Players.top
call Players[i].errorOccured()
set i = i + 1
endloop
call PlayingPlayers.reset()
endfunction
function InitTrig_ErrorOccurred takes nothing returns nothing
set gg_trg_ErrorOccurred = CreateTrigger()
call TriggerAddAction(gg_trg_ErrorOccurred, function Trig_ErrorOccured_Actions)
endfunction
Метод игрока, который вызывает триггер выше.
method errorOccured takes nothing returns nothing
call field.errorOccured()
if playing then
set playing = false
set inGame = false
call showGrid(false)
call GroupEnumUnitsInRect(ProxyGroup, field.playerarea, LightDeleteUnits)
endif
endmethod
Как правило, данный метод вызывает "лёгкое" удаление всех остальных объектов и структур, дабы не допустить повторных ошибок и пролагов.
Пример использования.
//! textmacro CustomArray takes name, type, size, index, err
struct $name$
private $type$ array objects[$size$]
readonly integer top = -1
method operator [] takes integer i returns $type$
return objects[i]
endmethod
method addToArray takes $type$ obj returns nothing
if obj.$index$ == -1 then
set top = top + 1
static if ErrorDetectionEnabled_CustomArray and $err$ then
if top == $size$ then
call ErrorOccurred("not enough cells in $name$ " + I2S(this) + ". Current amount of cells is " + I2S($size$), "$name$Cells")
endif
endif
set objects[top] = obj
set obj.$index$ = top
//call DebugMsg("$type$ " + I2S(obj) + " with index " + I2S(top) + " is added to $name$.")
else
call ErrorOccurred("an attempt of $type$ " + I2S(obj) + " to be added to $name$ " + I2S(this) + " second time", "$name$Add")
endif
endmethod
method deleteFromArray takes $type$ obj returns nothing
local integer i = obj.$index$
if i > -1 then
if top > i then
set objects[i] = objects[top]
set objects[i].$index$ = i
endif
set top = top - 1
set obj.$index$ = -1
//call DebugMsg("$type$ " + I2S(obj) + " with index " + I2S(i) + " is removed from $name$.")
else
call ErrorOccurred("an attempt of $type$ " + I2S(obj) + " to be deleted from $name$ " + I2S(this) + " second time", "$name$Delete")
endif
endmethod
method reset takes nothing returns nothing
set this.top = -1
endmethod
endstruct
//! endtextmacro
Макрос выше определяет структуру, которая создаёт массивы для указанного в макросе типа. Причём данный тип обязан иметь поле для хранения своего индекса.
Код под катом позволяет отлавливать и логгировать некоторую информацию об ошибках во время игры.
Это делается очень просто. Заходим на любую melee карту, выходим, затем запускаем карту, где есть юнит со скрытой способностью через координаты 0, -11. Выделяем юнита, ловим краш. Как минимум на 1.31 проблемы нет. Судя по всему, проблема в том, что на первой карте есть декор или разрушаемые объекты.
Нифига не проще, когда я делал карту на заказ, сам решил писать на 1.26 и как же я выл, когда я просто не мог снизить уровень улучшения или изменить описание способности, ну то есть заюзать функционал патча 1.29.
Хотя любой патч в итоге приводит к вою, ибо ни один из них не является полноценным.
Можно. Весь API 1.26 присутствует в последующих патчах, причём даже местами поправленный.
100500 нативок баганых в 1.31
Ровно столько же, сколько в 1.26. Чего стоят баги функций таймеров, которые существуют с релиза игры.
Почитай блоги драколича и ты много узнаешь об этой игре и ее "патчах".
Я читал.
И тут внимание вопрос - это я в этом виноват, некачественно делаю наверное
Именно так. Я же умудрился сделать карту, которая нормально работает и на 1.26, и на 1.29, и на 1.31, и на перековке. Причём это не потребовало от меня никаких усилий.
Близзарды же умудрились сделать кампанию так, что она работает и на 1.26, и на 1.29, и на 1.31, и на перековке. Более того, они эту кампанию два раза продали. А сколько раз вы продали свои "качественные" карты? То-то же.
Да, на последних патчах есть проблемы, которых нет на 1.26. Но на последних патчах нет и некоторых проблем, которые есть на 1.26. Некоторые проблемы есть как в 1.26, так и в последних патчах. Ты такой же фанатик, как и берги, только наоборот.
Но всё же хотел бы уточнить, а какие-такие проблемы есть на 1.29 и 1.31, что они прямо ломают карту? Конкретный воспроизводимый пример (свои "качественные" карты кидать не нужно), можно скинуть ссылку на блог лича, если там подробно описан случай напрочь ломающего бага.
Я говорю, что все патчи что выпускали близы после 1.26, постоянно что-то ломали и вызывали нервный тик не только у меня
Это смешно, просто потому что у нормальных людей нервный тик происходить начал с 1.24)
function GetSqrDistancePoints takes real x1, real y1, real x2, real y2 returns real
return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)
endfunction
function GetDistancePoints takes real x1, real y1, real x2, real y2 returns real
return SquareRoot((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
endfunction
function GetSqrDistanceWidgetPoint takes widget w, real x, real y returns real
local real dx = GetWidgetX(w) - x
local real dy = GetWidgetY(w) - y
return dx * dx + dy * dy
endfunction
function GetDistanceWidgetPoint takes widget w, real x, real y returns real
return SquareRoot(GetSqrDistanceWidgetPoint(w, x, y))
endfunction
function GetSqrDistanceWidgets takes widget w1, widget w2 returns real
local real dx = GetWidgetX(w1) - GetWidgetX(w2)
local real dy = GetWidgetY(w1) - GetWidgetY(w2)
return dx * dx + dy * dy
endfunction
function GetDistanceWidgets takes widget w1, widget w2 returns real
return SquareRoot(GetSqrDistanceWidgets(w1, w2))
endfunction
GetDistancePoints возвращает расстояние между двумя точками.
GetDistanceWidgetPoint возвращает расстояние между точкой и виджетом. Виджет - юнит, предмет или разрушаемый объект.
GetDistanceWidgets возвращает расстояние между двумя виджетами. Виджеты могут быть разного типа, то есть можно передать юнита и предмет.
Функции с Sqr возвращают квадрат расстояния. Полезно в тех ситуациях, когда нужно сравнить расстояния, ибо для сравнения корень считать необязательно: если квадрат одного числа больше квадрата другого, то корень первого числа больше корня второго. Тем самым функции Sqr не делают лишних вычислений и более точны в сравнениях.
С учётом того, что набор действий на каждого юнита одинаковый, нет смысла создавать триггер на каждого юнита. Достаточно создать один триггер с указанным набором действий и на него вешать события получения урона.
» WarCraft 3 / Проблемы с редактором
» WarCraft 3 / кое что о джассе
» WarCraft 3 / Хэш-таблицы в vJass
Ред. PT153
» WarCraft 3 / Проблемы с редактором
» WarCraft 3 / Warcraft 3 Reforged Взломан!
» WarCraft 3 / Warcraft 3 Reforged Взломан!
Ред. PT153
» WarCraft 3 / Начала внезапно вылетать карта. (редактор 1.26а)
А когда вылет происходит? Я запустил в карту, она работает.
» WarCraft 3 / Обучение jass
Автор в своём первом ролике лишь подкидывает мутации и слухи в копилку, не подтверждая свои слова ничем. Поэтому я и написал: Зачем мне смотреть рентв, оформленное в стиле вара? Да не то что мне, а вообще кому-то.
Ред. PT153
» WarCraft 3 / Обучение jass
» WarCraft 3 / Замена миникарты в лобби на превью в Reforge
Ред. PT153
» WarCraft 3 / Замена миникарты в лобби на превью в Reforge
» WarCraft 3 / Обучение jass
Ред. PT153
» WarCraft 3 / Обучение jass
Ред. PT153
» WarCraft 3 / Стальной вихрь (whirlwind) и Заводной зверь
» WarCraft 3 / Удаленные юниты и триггеры остаются висеть в памяти (vJass).
Ред. PT153
» WarCraft 3 / Структуры в джассе: смещение без очистки и вытекающие проблемы.
Второй проблемы в высокоуровневых языках быть не может, просто потому что объект остаётся в памяти до тех пор, пока на него ссылаются. Во время выполнения JASS никак нельзя узнать, сколько переменных ссылаются на то или иное число, дабы отложить вызов метода destroy, не говоря уже о том, что нет никакой информации, какой именно destroy нужно отложить. Поэтому её тоже решить невозможно.
Впрочем, можно оставить только Trig_ErrorOccured_Actions и вызвать её через .execute(), vJass сам сделает для неё триггер.
» WarCraft 3 / Удаленные юниты и триггеры остаются висеть в памяти (vJass).
» WarCraft 3 / Warcraft 3 Reforged Взломан!
Хотя любой патч в итоге приводит к вою, ибо ни один из них не является полноценным.
» WarCraft 3 / Warcraft 3 Reforged Взломан!
Близзарды же умудрились сделать кампанию так, что она работает и на 1.26, и на 1.29, и на 1.31, и на перековке. Более того, они эту кампанию два раза продали. А сколько раз вы продали свои "качественные" карты? То-то же.
» WarCraft 3 / Удаленные юниты и триггеры остаются висеть в памяти (vJass).
Ред. PT153
» WarCraft 3 / Узнать расстояние между юнитами
Ред. PT153
» WarCraft 3 / Warcraft 3 Reforged Взломан!
» WarCraft 3 / Warcraft 3 Reforged Взломан!
» WarCraft 3 / Удаленные юниты и триггеры остаются висеть в памяти (vJass).
» WarCraft 3 / Warcraft 3 Reforged Взломан!