Всем доброго времени суток! Собственно, сам вопрос, в заголовке темы. Бьюсь с тем, чтобы заставить компьютера использовать ополченцев для защиты лагеря при условии, что рудник истощился. Пробовал
call CampaignDefender(1, goldMiners + (lumberjacks - 2), MILITIA)
и
call StartUnit(goldMiners + (lumberjacks - 2), MILITIA, 0)
Никакого эффекта. Уже думал попробовать покопать в сторону механизма с сфинксами и лучницами на гиппогрифах, помнил, что там специальная функция была, но когда нашел код функции, увидел, что она исключительно для этих двух юнитов и все. Возможно, механика с ополченцем подобна превращению послушника в тень? Но перерыл скрипты кампаний, нигде не могу найти, чтобы ИИ строил тень. В общем, буду благодарен за советы по теме.

В общем порядком намучившись, все же пришел к выводу, что ребята писавшие АМАИ неспроста не юзали экспрешены, по всей видимости они по какой то причине(кривизна варкрафта привет) не работают в скриптах ИИ. Пришлось написать свой велосипед, очень похожий на то, что есть у них в принципе. Функция выборки рабочих игрока:
globals
	constant player thisPlayer = Player(1)  // В моем случае синий игрок
	...
endglobals

...

//============================================================================
//  Выбираем работников нашего игрока
//============================================================================
function GetPlayerWorkers takes nothing returns group
	local group playerWorkers = null
	local group allWorkers = null
	local unit regularWorker = null
	
	set playerWorkers = CreateGroup()
	set allWorkers = CreateGroup()
	
	call GroupEnumUnitsOfType(allWorkers, "Peasant", null)
	
	loop
		set regularWorker = FirstOfGroup(allWorkers)
		exitwhen regularWorker == null
		
		if GetOwningPlayer(regularWorker) == thisPlayer then
			call GroupAddUnit(playerWorkers, regularWorker)
		endif
		
		call GroupRemoveUnit(allWorkers, regularWorker)
	endloop
	
	return playerWorkers
endfunction
И юзаем нашу функцию:
//============================================================================
//  Отряды защиты лагеря
//============================================================================
function Defenders takes nothing returns nothing
	local group playerWorkers = null
	
	...
	
	set playerWorkers = GetPlayerWorkers()
		
	call GroupImmediateOrder(playerWorkers, "militia")
	call GroupClear(playerWorkers)
	
	call CampaignDefender(1, goldMiners + lumberjacks, MILITIA)
	
	...
	
endfunction
Возможно кому то будет полезно.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
15
quq_CCCP, я думаю мы оба понимаем, что это костыли. У меня почти получилось, я раскопал на гитхабе исходники АМАИ, правда их методика не совсем мне нравится, но все же я убедился в том, что надо вызывать способность напрямую, сам комп этого не сделает без прямого приказа. Пока что так:
local group workers = null
local unit regularPeasant = null
local boolexpr expression = null

...

set workers = CreateGroup()
set expression = Filter(function GetPlayerWorkersExpression)
call GroupEnumUnitsOfType(workers, "Peasant", expression)
call GroupImmediateOrder(workers, "militia")

// Проверка
set countUnits = 0
loop
	set regularPeasant = FirstOfGroup(workers)
	exitwhen regularPeasant == null
	set countUnits = countUnits + 1
	call GroupRemoveUnit(workers, regularPeasant)
endloop

call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, "Count: " +  I2S(countUnits))
, где функция GetPlayerWorkersExpression:
function GetPlayerWorkersExpression takes nothing returns boolean
	return GetOwningPlayer(GetFilterUnit()) == thisPlayer
endfunction
Это работает, работники стали записываться в ополчение, но пока у меня не получается разрешить 2 проблемы:
  1. Я не могу осознать, что не так с экспрешеном, функция возвращает всегда False, предположительно причина в функции GetFilterUnit, полагаю, что она всегда возвращает null. А без экспрешена выбираются вообще все работники на карте, вне зависимости от того, какому игроку они принадлежат и бегут к ратушам хвататься за оружие.
  2. По совершенно не ясной для меня причине криво работает функция конвертации целого числа в строку. Мне выводится пустота, т.е. Count:
Я пробовал выводить разные числа для интереса, он начинает выводить всякую дичь: frostarmor, music, имя одного из игроков, что угодно, но не числа.
32
Код выше в ИИ выполняется или в war3map.3?
Насчет костылей, увы, все этими костылями делается.в кампании у ИИ дерижабли в ратуше продаются...
15
quq_CCCP, в самом скрипте ИИ. По поводу дирижаблей знаю, близзы не особо заморачивались конечно. А может хотели исключить ситуацию, чтобы игрок просек фишку с покупкой дирижаблей и подлавливал бота на покупке дирижабля(как можно подловить АМАИ у таверны на покупке героя или у лавки гоблина на покупке предметов).
32
Meddin, не у верен что эти нативки корректно пашут в ИИ потоке, фильтр правильный? Дебаг кого возвращяет?
15
quq_CCCP, фильтр должен пахать как надо, даже в Blizzard.j есть подобный фильтр. По поводу дебага: честно говоря не знаю, как тут правильно заниматься этим, я и пытаюсь вместо него хотя бы на экран выводить количество юнитов, чтобы понять, сколько рабочих он занес в группу.
15
В общем порядком намучившись, все же пришел к выводу, что ребята писавшие АМАИ неспроста не юзали экспрешены, по всей видимости они по какой то причине(кривизна варкрафта привет) не работают в скриптах ИИ. Пришлось написать свой велосипед, очень похожий на то, что есть у них в принципе. Функция выборки рабочих игрока:
globals
	constant player thisPlayer = Player(1)  // В моем случае синий игрок
	...
endglobals

...

//============================================================================
//  Выбираем работников нашего игрока
//============================================================================
function GetPlayerWorkers takes nothing returns group
	local group playerWorkers = null
	local group allWorkers = null
	local unit regularWorker = null
	
	set playerWorkers = CreateGroup()
	set allWorkers = CreateGroup()
	
	call GroupEnumUnitsOfType(allWorkers, "Peasant", null)
	
	loop
		set regularWorker = FirstOfGroup(allWorkers)
		exitwhen regularWorker == null
		
		if GetOwningPlayer(regularWorker) == thisPlayer then
			call GroupAddUnit(playerWorkers, regularWorker)
		endif
		
		call GroupRemoveUnit(allWorkers, regularWorker)
	endloop
	
	return playerWorkers
endfunction
И юзаем нашу функцию:
//============================================================================
//  Отряды защиты лагеря
//============================================================================
function Defenders takes nothing returns nothing
	local group playerWorkers = null
	
	...
	
	set playerWorkers = GetPlayerWorkers()
		
	call GroupImmediateOrder(playerWorkers, "militia")
	call GroupClear(playerWorkers)
	
	call CampaignDefender(1, goldMiners + lumberjacks, MILITIA)
	
	...
	
endfunction
Возможно кому то будет полезно.
Принятый ответ
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.