30

» WarCraft 3 / AdicHelper?

При обращении к переменной без значения поток обрывается.
Правда? А посему декларация переменных поток не сбрасывается?
Вот у массивов все ячейки имеют дефолтное значение
А не обращение к несуществующему элементу массива возвращало null?
30

» WarCraft 3 / Создание проклятого рудника через триггеры

Как видно из blizzard.j они тупо удаляют рудник и ставят порченный.
--===========================================================================
-- Starting Units for Undead Players
-- - 1 Necropolis, placed at start location
-- - 1 Haunted Gold Mine, placed on nearest gold mine
-- - 3 Acolytes, placed between start location and nearest gold mine
-- - 1 Ghoul, placed between start location and nearest gold mine
-- - Blight, centered on nearest gold mine, spread across a "large area"
--
---@param whichPlayer player
---@param startLoc location
---@param doHeroes boolean
---@param doCamera boolean
---@param doPreload boolean
function MeleeStartingUnitsUndead(whichPlayer, startLoc, doHeroes, doCamera, doPreload)
	local useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO) ---@type boolean
	local unitSpacing = 64.00 ---@type real
	local nearestMine = nil ---@type unit
	local nearMineLoc = nil ---@type location
	local nearTownLoc = nil ---@type location
	local heroLoc = nil ---@type location
	local peonX = nil ---@type real
	local peonY = nil ---@type real
	local ghoulX = nil ---@type real
	local ghoulY = nil ---@type real
	
	if (doPreload) then
		Preloader( "scripts\\UndeadMelee.pld" )
	end
	
	nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
	if (nearestMine ~= nil ) then
		-- Spawn Necropolis at the start location.
		CreateUnitAtLoc(whichPlayer, FourCC('unpl'), startLoc, bj_UNIT_FACING)
		
		-- Replace the nearest gold mine with a blighted version.
		nearestMine = BlightGoldMineForPlayerBJ(nearestMine, whichPlayer)
		
		-- Spawn Ghoul near the Necropolis.
		nearTownLoc = MeleeGetProjectedLoc(startLoc, GetUnitLoc(nearestMine), 288, 0)
		ghoulX = GetLocationX(nearTownLoc)
		ghoulY = GetLocationY(nearTownLoc)
		bj_ghoul[GetPlayerId(whichPlayer)] = CreateUnit(whichPlayer, FourCC('ugho'), ghoulX + 0.00 * unitSpacing, ghoulY + 0.00 * unitSpacing, bj_UNIT_FACING)
		
		-- Spawn Acolytes near the mine.
		nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
		peonX = GetLocationX(nearMineLoc)
		peonY = GetLocationY(nearMineLoc)
		CreateUnit(whichPlayer, FourCC('uaco'), peonX + 0.00 * unitSpacing, peonY + 0.50 * unitSpacing, bj_UNIT_FACING)
		CreateUnit(whichPlayer, FourCC('uaco'), peonX + 0.65 * unitSpacing, peonY - 0.50 * unitSpacing, bj_UNIT_FACING)
		CreateUnit(whichPlayer, FourCC('uaco'), peonX - 0.65 * unitSpacing, peonY - 0.50 * unitSpacing, bj_UNIT_FACING)
		
		-- Create a patch of blight around the gold mine.
		SetBlightLoc(whichPlayer,nearMineLoc, 768, true)
		
		-- Set random hero spawn point to be off to the side of the start location.
		heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
	else
		-- Spawn Necropolis at the start location.
		CreateUnitAtLoc(whichPlayer, FourCC('unpl'), startLoc, bj_UNIT_FACING)
		
		-- Spawn Acolytes and Ghoul directly south of the Necropolis.
		peonX = GetLocationX(startLoc)
		peonY = GetLocationY(startLoc) - 224.00
		CreateUnit(whichPlayer, FourCC('uaco'), peonX - 1.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
		CreateUnit(whichPlayer, FourCC('uaco'), peonX - 0.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
		CreateUnit(whichPlayer, FourCC('uaco'), peonX + 0.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
		CreateUnit(whichPlayer, FourCC('ugho'), peonX + 1.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
		
		-- Create a patch of blight around the start location.
		SetBlightLoc(whichPlayer,startLoc, 768, true)
		
		-- Set random hero spawn point to be just south of the start location.
		heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
	end
	
	if (doHeroes) then
		-- If the "Random Hero" option is set, start the player with a random hero.
		-- Otherwise, give them a "free hero" token.
		if useRandomHero then
			MeleeRandomHeroLoc(whichPlayer, FourCC('Udea'), FourCC('Udre'), FourCC('Ulic'), FourCC('Ucrl'), heroLoc)
		else
			SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
		end
	end
	
	if (doCamera) then
		-- Center the camera on the initial Acolytes.
		SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
		SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
	end
end
Вот этой функцией
--===========================================================================
-- Replaces a gold mine with a blighted gold mine for the given player.
--
---@param goldMine unit
---@param whichPlayer player
---@return unit
function BlightGoldMineForPlayerBJ(goldMine, whichPlayer)
	local mineX = nil ---@type real
	local mineY = nil ---@type real
	local mineGold = nil ---@type integer
	local newMine = nil ---@type unit
	
	-- Make sure we're replacing a Gold Mine and not some other type of unit.
	if GetUnitTypeId(goldMine) ~= FourCC('ngol') then
		return nil
	end
	
	-- Save the Gold Mine's properties and remove it.
	mineX = GetUnitX(goldMine)
	mineY = GetUnitY(goldMine)
	mineGold = GetResourceAmount(goldMine)
	RemoveUnit(goldMine)
	
	-- Create a Haunted Gold Mine to replace the Gold Mine.
	newMine = CreateBlightedGoldmine(whichPlayer, mineX, mineY, bj_UNIT_FACING)
	SetResourceAmount(newMine, mineGold)
	return newMine
end
30

» WarCraft 3 / AdicHelper?

ты всегда пытаешься использовать переменную без значения. Это ошибка.
А в чём проблема переменной без значения?

zinc например позволял их объявлять.
local real x, y = 0.5, z
30

» WarCraft 3 / Как сделать для каждого игрока отдельный MultiBoard?

Где? Почему у меня не десинкают?
В комментраиях же. Сам ещё не работал с мультибордами, поэтому ничего сказать не могу.
30

» WarCraft 3 / Как сделать для каждого игрока отдельный MultiBoard?

Через локал плеера можно и в одном МБорде всё всем показывать.
Много раз слышал, что мультиборды десинкают и поэтому для каждого игрока свой создают.
30

» WarCraft 3 / Хеш-таблица и юнит

Может в переменные заносить тип юнита и номер его владельца.
Так хэндл юнита и так хранит эту информацию.
30

» WarCraft 3 / Джас код на удаление точек

и усидеть на двух стульях (GUI/Jass) будет становиться все сложнее
Особенно, когда все перейдут на lua)
30

» Наследие Альянса / Релиз кампании "Последний Страж Лордерона"

а что плохого в невидимых стенах?
Во второй миссии главный герой упирается в невидимую стену и пока не убьёт гулей, пройти не может. Удобно)
30

» Наследие Альянса / Релиз кампании "Последний Страж Лордерона"

Озвучка понравилась, прям как на пиратских дисках.
Но вот клише с неуязвимыми неписями и невидимыми стенами, серьёзно?
30

» WarCraft 3 / Как сделать надпись "загрузка..." другого цвета?

как сменить фон надписи "идёт загрузка" с синего цвета на другой
Вот этот?
Загруженные файлы
30

» WarCraft 3 / Нужно ли собирать триггеры с одинаковым условием в один

При этом, если сделать для двух диалогов переменные Skip1 и Skip2, то всё исправно работает.
После завершения первого диалога Skip возвращается в false?
30

» WarCraft 3 / Передвижение юнитов через спел на Хеш-таблице

Я пока вижу только проблему, когда в одну цель несколько похищений.
И ещё одна проблема, если делать лимит целей: нужно обрывать drain, которому меньше всего жить осталось.
30

» WarCraft 3 / Передвижение юнитов через спел на Хеш-таблице

Это можно сделать через сохранение групп в хеш-таблицу.
К сожалению молнии нельзя сохранять в группы.
В смысле, равномерно? А изначально там неравномерное распределение?
Если одну цель сосут два кастера, то урон/хп происходят только от самой сильной абилки и хп распределяется между кастерами.
Можно записывать кастера в хеш-таблицу с хэндлом цели.
Представьте пять кастеров, каждый из которых применил заклинание один на другого. Притом между двумя кастерами не должно отрисовываться двух молний.
хватит всем сувать Lua, проще всего GUI
Хватит всем набирать код руками, ноги выбор мастеров.
30

» WarCraft 3 / Передвижение юнитов через спел на Хеш-таблице

не вижу смысла сохранять двумерные массивы в хеш-таблицу.
Делал заклинание и хотел сделать множественное применение, но возникла проблема хранения всех целей на кастере и всех кастеров на цели. Плюс ещё кучу всего, чтоб равномерно распределять хп между всеми применившими заклинание. Притом хотел ещё учесть такой вариант, что если два кастера применяют заклинание у одной цели, то первый применивший дамажил второго. Тут то мне таблиц и нехватило.
Функции? Их разве можно вообще куда-либо сохранять?
В lua их даже возвращать можно)
function sum(a)
	return function(b)
		return a + b
	end
end
print(sum(2)(3)) --> 5

Ещё можно удобно сохранять данные
Загруженные файлы
30

» WarCraft 3 / Передвижение юнитов через спел на Хеш-таблице

Хеш-таблица — универсальный хранитель информации.
Как сможете без лишних сущностей сохранить n двумерных массивов на хэндл юнита, тогда я вам поверю. За сохранение в хэштаблице безымянной функции я вообще молчу.
30

» WarCraft 3 / Передвижение юнитов через спел на Хеш-таблице

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

» WarCraft 3 / Конвертация в строку

trim обычно убирает символы отступа вначале и конце.
Так передайте в found пробел, он и уберёт. Я его для комманд чата писал и посему перевод строки не предусматривал.
30

» WarCraft 3 / Конвертация в строку

PT153, я целую библиотеку хороших функций накатал)
// Выводим сообщения
MessageTimed(string str, real time)
Message(string str)
MessageForPlayerTimed(player p, string str, real time)
MessageForPlayer(player p, string str)

// Очищаем строку сообщения
ClearTextMessagesForPlayer(player p)

// Получаем имя игрока
GetPlayerColorString(player p) -> string
GetPlayerNameColored(player p)  -> string

// Обрезаем крайние символы
LTrim(string str, string found) -> string
RTrim(string str, string found) -> string
Trim(string str, string found) -> string
// Примеры
LTrim("---T-r-i-m---", "-"); // T-r-i-m---
RTrim("---T-r-i-m---", "-"); // ---T-r-i-m
Trim("---T-r-i-m---", "-"); // T-r-i-m

// Конвертируем boolean в строку
B2S(boolean b) -> string
// Примеры
B2S(true); // true
B2S(!true); // false

// Превращаем строку в равкод
S2RAW(string ObjectId) -> integer
// Пример
S2RAW("hfoo"); // 1751543663
    
// Превращаем равкод в строку
RAW2S(integer ObjectId) -> string
// Пример
RAW2S(1751543663); // hfoo

// Заменяем подстроку
StringReplaceCounted(string str, string found, string replace, integer count) -> string
StringReplace(string str, string found, string replace) -> string
// Примеры
StringReplaceCounted("old old old old old", "new", 2); // new new old old old
StringReplaceCounted("old old old old old", "new", -2); // old old old new new
StringReplace("old old old old old", "new"); // new new new new new

// Склоняем строку в зависимости от числа
Declension(integer number, string dec1, string dec4, string dec5);
/* Описание
number - число, от которого склонять
dec1 - вариант склонения для числа 1, например "предмет"
dec4 - вариант склонения для числа 4, например "предмета"
dec5 - вариант склонения для числа 5, например "предметов"
*/
// Пример
Declension(100500, "предмет", "предмета", "предметов") // предметов

// Склоняем строку в зависимости от числа с заменой подстроки и учётом нуля
Declenser(integer number, string found, string dec0, string dec1, string dec4, string dec5) -> string
/* Описание
number - число, от которого склонять
found - подстрока, которая будет заменена на number
dec0 - вариант строки для number == 0, например "Рюкзак пуст"
dec1 - вариант склонения для числа 1, например "В рюкзаке %count% предмет"
dec4 - вариант склонения для числа 4, например "В рюкзаке %count% предмета"
dec5 - вариант склонения для числа 5, например "В рюкзаке %count% предметов"
*/
// Пример
Declenser(
	100500,
	"%count%",
	"Рюкзак пуст", 
	"В рюкзаке %count% предмет",
	"В рюкзаке %count% предмета",
	"В рюкзаке %count% предметов"
); // В рюкзаке 100500 предметов