Вопрос энтузиастам.
Стоит задача, определить в какой версии Warcraft III запущена карта. И если она запущена в актуальной версии (1.32+), то использовать новую функцию, появившуюся в этой версии. При этом код карты должен компилироваться и на старой (1.26) и на новой (1.32+) версиях.
Для определения версии я пока только придумал использовать следующий код, основанный на том, что раньше Siege Engine требовал 3 пищи, а сейчас 4 пищи:
//===========================================================================
//Узнаём версию игры
//===========================================================================
function IsOld126Version takes nothing returns boolean
	return GetFoodUsed('hmtt')==3 //Самоходная мортира (Siege Engine)
endfunction
Но баланс может поменяться в одной из будущих версий, это выглядит не надёжно.
Для вызова новых функций без потери успешной компиляции в старых версиях можно использовать функцию:
if not(IsOld126Version) then 
	call ExecuteFunc("BlzChangeMinimapTerrainTex")
endif
Но таким образом можно только запустить функции, которые не имеют аргументов.
Вопросы:
  1. Есть ли более надёжный способ узнать версию игры?
  2. Можно ли как-то использовать ExecuteFunc с аргументами?
  3. Можно ли включить в карту каким либо образом описание функции BlzChangeMinimapTerrainTex(string s) без полной подмены файла common.j?

Принятый ответ

Да. Вызвать новые функции можно. Вот здесь подробнее, как это сделать, на примере задачи по установке preview:
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
23
4 года назад
0
бедняжка не мечтай чтобы 1 карта имела на 1.26 и 1.31+
0
22
4 года назад
0
pro100master:
бедняжка не мечтай чтобы 1 карта имела на 1.26 и 1.31+
Сделал уже xgm.guru/p/blog-makkad/northrend-rpg . Там много подобных костылей, но вроде всё удачно сшилось. Осталось только сделать Preview для 1.31+.
0
32
4 года назад
0
Способы есть и через BlzChangeMinimapTerrainTex вполне нормальный, но смысл всего происходящего, я не думаю что можно в карту 126 патча засунуть рефордж код и он заработает в рефордже, такое проверялось?
2
22
4 года назад
2
Bergi_Bear:
Способы есть и через BlzChangeMinimapTerrainTex вполне нормальный, но смысл всего происходящего, я не думаю что можно в карту 126 патча засунуть рефордж код и он заработает в рефордже, такое проверялось?
Да. Работает через ExecuteFunc.
0
32
4 года назад
0
makkad:
Да. Работает через ExecuteFunc.
А на каком этапе внедрение кода новых патчей происходит? Просто не могу понять как в этом экзекут помогает. Но верю...
Это довольно таки круто
0
22
4 года назад
0
Bergi_Bear:
makkad:
Да. Работает через ExecuteFunc.
А на каком этапе внедрение кода новых патчей происходит? Просто не могу понять как в этом экзекут помогает. Но верю...
Это довольно таки круто
Вроде ничего крутого.... наверное я что-то не то написал. В файлах рефорджа эти функции всегда были, и вот они и запускаются. В 1.26 этих функций нет, и к ним просто код карты просто не обращается.
Конечно, поменять файл миникарты через BlzChangeMinimapTerrainTex в 1.26 не получится. Но если ту же карту запустить в 1.32 то там это прокатит, если придумать как передать аргументы через ExecuteFunc. Функции без аргументов срабатывают.
Думаю, исследователь работу функций типа Preload. Они же работают в 1.26 и 1.32?
1
29
4 года назад
Отредактирован Волчачка
1
Плохая идея так определять версии патча. Вот если варик имел бы Lua сценарий с патча 1.26a то проблем бы и таких стараний с костылинрованием на версию не было. Хотя более менее сработало, если была бы функция с самого начала для патча GetVersionPatch. А если был бы lua сценарий с патча 1.26, то ты мог просто проверять по существованию функций. Даже не пришлось бы прибегать в проверки версий. Хотя, ты можешь ещё проверять через GetObjectName(), на наличие добавленных: способностей, усовершенствований или войск; которых нет в 1.26.
1
32
4 года назад
1
Если не изменяет память, чтение записи близарды так и не закрыли на 1.31+ и можно все еще ломануть массив, посмотреть какие будут данные на выходе, мемхак на старшие версии где то тут валялся как собственно и на хайве полно было карт на эту тему - определение версии игры.
Ну а аргументы передаешь тупо через глобалки, но полную совместимость ты не получишь, карта будет не полноценной на одной из версий.
1
15
4 года назад
1
Надёжнее можно проверять цвет ID игрока 12.
Так как в новом патче больше игроков.
Загруженные файлы
1
32
4 года назад
Отредактирован Берги
1
DarkLigthing, ТОЧНО BJ_Max_SLOT_Player
12 - 126, 24 - рефордж
0
37
4 года назад
Отредактирован ScorpioT1000
0
есть же кейворд native в vjass
объяви нужные нативки 1.32 внутри карты
я так понимаю, главная проблема - это компилятор, а не сама игра. Игра работает в рантайме


хотя в 1.32 будет проблема редекларации
придется весь common.j из 1.32 тащить к себе
0
26
4 года назад
0
А через VersionGet() он не вернёт реф?)))
0
32
4 года назад
0
--  Game API
---@return version
function VersionGet() end    -- (native)
---@param whichVersion version
---@return boolean
function VersionCompatible(whichVersion) end    -- (native)
---@param whichVersion version
---@return boolean
function VersionSupported(whichVersion) end    -- (native)
0
22
4 года назад
0
Bergi_Bear:
--  Game API
---@return version
function VersionGet() end    -- (native)
---@param whichVersion version
---@return boolean
function VersionCompatible(whichVersion) end    -- (native)
---@param whichVersion version
---@return boolean
function VersionSupported(whichVersion) end    -- (native)
Это только, чтобы узнать VERSION_REIGN_OF_CHAOS или VERSION_FROZEN_THRONE
0
32
4 года назад
0
Да спасибо, бесполезняк какой-то.
Не вижу минусов у bj_MAX_PLAYER_SLOTS
0
37
4 года назад
0
0
32
4 года назад
Отредактирован Берги
0
ScorpioT1000:
это переходной и не стоит задачи определять этот патч, надо лишь различать 126 и последний 132+
0
22
4 года назад
0
Всем спасибо за ответы. Похоже, малой кровью этого не добиться. С полной подменой common.j (и blizzard.j заодно) надо будет поэкспериментировать.
0
37
4 года назад
Отредактирован ScorpioT1000
0
Bergi_Bear, там 24 игрока, но константу не обновили
4
28
4 года назад
Отредактирован PT153
4
Уже давно всё придумали. Вот ресурс. Необходимо добавить только детект для версии 1.32.
ScorpioT1000:
там 24 игрока, но константу не обновили
Всё там обновили, теперь у этой константы не hardcoded значение, а значение из нативки. Для карт, созданных в WE до 1.29, нативка возвращает 12, после - 24.
    // Game constants
    constant integer   bj_MAX_INVENTORY                 =  6
    constant integer   bj_MAX_PLAYERS                   =  GetBJMaxPlayers()
    constant integer   bj_PLAYER_NEUTRAL_VICTIM         =  GetBJPlayerNeutralVictim()
    constant integer   bj_PLAYER_NEUTRAL_EXTRA          =  GetBJPlayerNeutralExtra()
    constant integer   bj_MAX_PLAYER_SLOTS              =  GetBJMaxPlayerSlots()
    constant integer   bj_MAX_SKELETONS                 =  25
    constant integer   bj_MAX_STOCK_ITEM_SLOTS          =  11
    constant integer   bj_MAX_STOCK_UNIT_SLOTS          =  11
    constant integer   bj_MAX_ITEM_LEVEL                =  10
Ответ удалённому комментарию ниже: так как HandleId равно -1, то объекта нет, потому и уничтожать не нужно.
Этот комментарий удален
0
22
4 года назад
Отредактирован makkad
0
PT153:
Уже давно всё придумали. Вот ресурс. Необходимо добавить только детект для версии 1.32.
ScorpioT1000:
там 24 игрока, но константу не обновили
Всё там обновили, теперь у этой константы не hardcoded значение, а значение из нативки. Для карт, созданных в WE до 1.29, нативка возвращает 12, после - 24.
    // Game constants
    constant integer   bj_MAX_INVENTORY                 =  6
    constant integer   bj_MAX_PLAYERS                   =  GetBJMaxPlayers()
    constant integer   bj_PLAYER_NEUTRAL_VICTIM         =  GetBJPlayerNeutralVictim()
    constant integer   bj_PLAYER_NEUTRAL_EXTRA          =  GetBJPlayerNeutralExtra()
    constant integer   bj_MAX_PLAYER_SLOTS              =  GetBJMaxPlayerSlots()
    constant integer   bj_MAX_SKELETONS                 =  25
    constant integer   bj_MAX_STOCK_ITEM_SLOTS          =  11
    constant integer   bj_MAX_STOCK_UNIT_SLOTS          =  11
    constant integer   bj_MAX_ITEM_LEVEL                =  10
Ответ удалённому комментарию ниже: так как HandleId равно -1, то объекта нет, потому и уничтожать не нужно.
Создал карту в 1.26. Запустил её в 1.32. Значение bj_MAX_PLAYER_SLOTS выдало 16.

"WINDOW_MODE_WINDOWED"==GetLocalizedString("WINDOW_MODE_WINDOWED")
True, если версия ниже 1.31. Должно хватить на практике для новых функций blz.
Загруженные файлы
0
28
4 года назад
0
Значение bj_MAX_PLAYER_SLOTS выдало 16.
Всё верно, если карту пересохранить в 1.29+, будет 28.
0
22
4 года назад
0
Форматирование
Хм... ну тогда от этого мало пользы. Я и так знаю, в какой я версии сохраняю карту.
0
22
3 года назад
0
Да. Вызвать новые функции можно. Вот здесь подробнее, как это сделать, на примере задачи по установке preview:
Принятый ответ
Чтобы оставить комментарий, пожалуйста, войдите на сайт.