Возился-возился, решение будет такое.
Нужно дать герою ВСЕ способности, а во время инициализации отключить все для всех игроков (Действие -> Игрок -> ...). А во время драфта включать те способности, которые выбрал игрок. Работает, только если 1 игрок = 1 герой.
function StringToPlayerColor takes string color returns playercolor
set color = StringCase(color, false)
if color == "red" then
return PLAYER_COLOR_RED
elseif color == "blue" then
return PLAYER_COLOR_BLUE
elseif color == "cyan" then
return PLAYER_COLOR_CYAN
elseif color == "purple" then
return PLAYER_COLOR_PURPLE
elseif color == "yellow" then
return PLAYER_COLOR_YELLOW
elseif color == "orange" then
return PLAYER_COLOR_ORANGE
elseif color == "green" then
return PLAYER_COLOR_GREEN
elseif color == "pink" then
return PLAYER_COLOR_PINK
elseif color == "light gray" then
return PLAYER_COLOR_LIGHT_GRAY
elseif color == "light blue" then
return PLAYER_COLOR_LIGHT_BLUE
elseif color == "aqua" then
return PLAYER_COLOR_AQUA
elseif color == "brown" then
return PLAYER_COLOR_BROWN
endif
return null
endfunction
function StringToPlayerId takes string color, player admin returns player
local integer i
local player p
local playercolor col = StringToPlayerColor(color)
if col != null then
set i = 0
loop
set p = Player(i)
// В вызове этой функции в триггере с событием на чат в качестве admin передаём GetTriggerPlayer().
// Сначала проверится, не админ ли это. Если это админ, дальнейшие условия скипаются.
// Если всё-таки не админ, проверяется статус. Если слот пуст или игрок вышел, дальнейшие условия скипаются.
// Если игрок всё ещё играет, то сверяем цвета. Если цвета не равны, то выходим из условия.
// Если всё правда, то возвращаем индекс или сразу игрока.
if p != admin and GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerColor(p) == col then
return p
endif
set i = i + 1
exitwhen i == bj_MAX_PLAYERS
endloop
endif
return null
endfunction
По поводу бара длительности: его нельзя убрать, иначе юнит исчезнет, но его можно поставить на паузу.
По поводу задержки: у героя нужно поставить длительность анимации до каста и после на 0.
Cделал обе эти вещи в это карте, второе у пивовара. Пример.
По поводу опыта: можно поставить получение опыта на 0% в действиях. Отключение опыта в том же меню работает плохо, от атак юнит всё равно будет получать опыт (или от убийств от зданий, если включено в константах, я так и не разобрался в этом).
т.е лимит не остановит и големов можно плодить хоть на весь экран.
Маг -- обычный юнит что ли?
Если да, то решение простое. Можно либо отключать способность на игрока во время вызова, и включать во время смерти голема, либо поставить требование на способность. Пока голема нет, у игрока есть дамми-юнит, который требуется для способности, когда голем призван, даммик убивается. Когда голем умирает, опять создаём этого даммика.
Если маг является героем, то не вижу проблемы, в кампании у Рексара могла быть только одна Миша, хоть первый и умирал.
емнип, нечто похожее работает в отношении скелетов некроманта, но это не точно
У Raise Dead есть только проверка на лимит, после смерти призывателя призванные скелеты не умирают.
Если нужно, чтобы при смерти призывателя умирал и голем, хеш вам в руки. По хендлу мага сохраняем в хеш голема, при смерти мага загружаем голема, убиваем, чистим хеш.
один из героев просто исчез, словно его юнита удалили
Скорее всего, произошла ошибка в сохранении юнита, и удалился не дамми, а герой, к которому дамми принадлежал.
Можно как-то посмотреть какой код выполнялся в реплее в тот момент?
Нет.
Как правило ремувается очень большое количество дамми
Следует сделать общую функцию для каждого подтипа юнита.
Дамми можно вообще не удалять, а ставить им отрицательную регенерацию или таймер на смерть (Timed life), как у призванных существ. Некоторых дамми можно удалять, как только они завершили кастовать спелл (события EVENT_UNIT_SPELL_ENDCAST, EVENT_PLAYER_UNIT_SPELL_ENDCAST).
Дебаг на RemoveUnit() можно поставить с помощью hook.
Вот как у меня в одной карте сделано создание и удаление дамми. Делал давно, сейчас знаю больше, потому можно сделать лучше.
Код
function DeleteDummy takes nothing returns nothing
local timer t= GetExpiredTimer()
local integer tH= GetHandleId(t)
call RemoveUnit(LoadUnitHandle(udg_Hash, tH, 1))
call RemoveSavedHandle(udg_Hash, tH, 1)
call DestroyTimer(t)
set t=null
endfunction
function CreateDummy takes player id,integer unitid,real x,real y,real face,real duration returns unit
local timer t
set bj_lastCreatedUnit=CreateUnit(id, unitid, x, y, face)
if duration > 0. then
// Вместо таймера лучше ставить временную жизнь через UnitApplyTimedLife().
set t=CreateTimer()
call SaveUnitHandle(udg_Hash, GetHandleId(t), 1, bj_lastCreatedUnit)
call TimerStart(t, duration, false, function DeleteDummy)
set t=null
else
// Тут достаточно лишь ENDCAST.
call TriggerRegisterUnitEvent(gg_trg_DummyFinishesCast, bj_lastCreatedUnit, EVENT_UNIT_SPELL_FINISH)
call TriggerRegisterUnitEvent(gg_trg_DummyFinishesCast, bj_lastCreatedUnit, EVENT_UNIT_SPELL_ENDCAST)
endif
return bj_lastCreatedUnit
endfunction
Залезь и глянь, возможно, для новых цветов таких переменных не завезли, так как их не в новом TESH. Если их нет, то можешь свои завести, уверен, все новые цвета можно получить через использование ConvertPlayerColor(12) -- ConvertPlayerColor(23).
Можно bj_setPlayerTargetColor заменить на локальную, которую даже можно не обнулять.
function StringToPlayerColor takes string color returns playercolor
set color = StringCase(color, false)
if color == "red" then
return PLAYER_COLOR_RED
elseif color == "blue" then
return PLAYER_COLOR_BLUE
elseif color == "cyan" then
return PLAYER_COLOR_CYAN
elseif color == "purple" then
return PLAYER_COLOR_PURPLE
elseif color == "yellow" then
return PLAYER_COLOR_YELLOW
elseif color == "orange" then
return PLAYER_COLOR_ORANGE
elseif color == "green" then
return PLAYER_COLOR_GREEN
elseif color == "pink" then
return PLAYER_COLOR_PINK
elseif color == "light gray" then
return PLAYER_COLOR_LIGHT_GRAY
elseif color == "light blue" then
return PLAYER_COLOR_LIGHT_BLUE
elseif color == "aqua" then
return PLAYER_COLOR_AQUA
elseif color == "brown" then
return PLAYER_COLOR_BROWN
endif
return null
endfunction
function StringToPlayerId takes string color returns integer
local integer i
set bj_setPlayerTargetColor = StringToPlayerColor(color)
if bj_setPlayerTargetColor != null then
set i = 0
loop
if GetPlayerColor(Player(i)) == bj_setPlayerTargetColor then
return i
endif
set i = i + 1
exitwhen i == bj_MAX_PLAYERS
endloop
endif
return -1
endfunction
Можно поступить иначе: создать структуру для играющих игроков с сохранением полученного объекта в структуры в какой-нибудь массив, в которой будет сохранятся строчный цвет игрока (который можно будет определить функцией, обратной StringToPlayerColor), а при написании в чат пробегаться по массиву игроков и смотреть, у кого же нужный цвет.
Можно так не заморачиваться, а менять цвет юнита входящего в область карты на цвет прикреплённый к игроку. А при смене цвета выбирать всех юнитов игрока и делать то же самое.
А можно вообще отключить выбор цвета в меню выбора карты.
Что значит unitToBuild (unitId в Id варианте функции)?
Я так полагаю, что туда можно просто передать любой приказ.
Цитата из твоего ответа.
По сути совет правильный, но приказ (имеется в виду skillmenu) указан неверно: OrderId("attributemodskill") = 852576
Это разные приказы, приказ skillmenu указан абсолютно верно, attributemodskill - другой приказ, это приказ повышения характеристик (равкод способности 'Aamk').
Ред. PT153
» WarCraft 3 / Как сделать выбор способности как в AbilityDraft из DoTA?
Нужно дать герою ВСЕ способности, а во время инициализации отключить все для всех игроков (Действие -> Игрок -> ...). А во время драфта включать те способности, которые выбрал игрок. Работает, только если 1 игрок = 1 герой.
» WarCraft 3 / Русификатор триггеров для обычного редактора и JNGP
JNGP не совместим с 1.28 версии.
» WarCraft 3 / Как получить номер игрока по его цвету
» WarCraft 3 / Как получить номер игрока по его цвету
Стоит завести свой массив игроков и искать в нём.
» WarCraft 3 / Русификатор триггеров для обычного редактора и JNGP
» WarCraft 3 / Как сделать выбор способности как в AbilityDraft из DoTA?
» WarCraft 3 / Юнит как Герой + его позиция
» WarCraft 3 / Как сделать выбор способности как в AbilityDraft из DoTA?
» WarCraft 3 / Как сделать прозрачную текстуру интерфейса в варкрафте 3?
» WarCraft 3 / Вопрос по ближней и дальней атаке.
Ред. PT153
» WarCraft 3 / Юнит как Герой + его позиция
По поводу задержки: у героя нужно поставить длительность анимации до каста и после на 0.
Cделал обе эти вещи в это карте, второе у пивовара.
Пример.
По поводу опыта: можно поставить получение опыта на 0% в действиях. Отключение опыта в том же меню работает плохо, от атак юнит всё равно будет получать опыт (или от убийств от зданий, если включено в константах, я так и не разобрался в этом).
» WarCraft 3 / Вопрос по ближней и дальней атаке.
Но с этим аккуратнее, даже в HotS с этим есть баги.
» WarCraft 3 / Иконки из Heroes of the Storm (3/4)
Ред. PT153
» WarCraft 3 / Смерть голема при смерти мага
Если да, то решение простое. Можно либо отключать способность на игрока во время вызова, и включать во время смерти голема, либо поставить требование на способность. Пока голема нет, у игрока есть дамми-юнит, который требуется для способности, когда голем призван, даммик убивается. Когда голем умирает, опять создаём этого даммика.
Если маг является героем, то не вижу проблемы, в кампании у Рексара могла быть только одна Миша, хоть первый и умирал.
» WarCraft 3 / Не скрывается абилка
» WarCraft 3 / Не скрывается абилка
Ред. PT153
» WarCraft 3 / Очень странный баг
Дамми можно вообще не удалять, а ставить им отрицательную регенерацию или таймер на смерть (Timed life), как у призванных существ. Некоторых дамми можно удалять, как только они завершили кастовать спелл (события EVENT_UNIT_SPELL_ENDCAST, EVENT_PLAYER_UNIT_SPELL_ENDCAST).
Ред. PT153
» WarCraft 3 / Некоторые функции юнитов
Открывать лучше MPQ Master.
» WarCraft 3 / Как получить номер игрока по его цвету
» WarCraft 3 / Вылетает редактор при попытке добавить способность в хеш-таблицу
Сохранить равкод способности можно через сохранение целочисленной (integer).
Ред. PT153
» WarCraft 3 / Как получить номер игрока по его цвету
Ред. PT153
» WarCraft 3 / Как получить номер игрока по его цвету
Ред. PT153
» WarCraft 3 / Как получить номер игрока по его цвету
» WarCraft 3 / Функции отдачи приказа
Ред. PT153
» WarCraft 3 / Функции отдачи приказа