создал ИИ сделал так чтоб ходили и били крипов все нормально работает создал триггер для того что бы ходили на базу если хп мало здесь возникла проблема если хп мало они дерутся до смерти как можно это реализовать вот скрины

Ты сам даешь им приказ двигаться через атаку, вместо того чтобы просто идти. Какой еще результат ожидается?
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
14
Vitamin:
Помоему для вашей цели лучше всего пойдет создание AI скрипта и подключение его через функцию SetMeleeAI
Пример AI скрипта ниже (если понимаете JASS, проблем в дальнешем в написании/изменении текущего не составит проблем)
AI Script
globals
	constant integer HOLY_BOLT	= 1095264354

	constant integer FOOTMAN 	= 1751543663
	constant integer KNIGHT		= 1751871081
	constant integer PRIEST		= 1752002674
	constant integer UTHER		= 1215657064

	group	g_hHurtUnitGroup	= CreateGroup()

	integer	g_iCaptainHomeX
	integer g_iCaptainHomeY

	integer g_iFountainOfLifeX
	integer g_iFountainOfLifeY

	unit 	g_hHero
endglobals

function B2S takes boolean b returns string
    if b then
        return "true"
    else
        return "false"
    endif
endfunction

function Dig2Str takes integer i returns string
    if i == 1 then
        return "1"
    elseif i == 2 then
        return "2"
    elseif i == 3 then
        return "3"
    elseif i == 4 then
        return "4"
    elseif i == 5 then
        return "5"
    elseif i == 6 then
        return "6"
    elseif i == 7 then
        return "7"
    elseif i == 8 then
        return "8"
    elseif i == 9 then
        return "9"
    else
        return "0"
    endif
endfunction

// Courtesy of AIAndy and Tommi. See source:
// http://www.hiveworkshop.com/threads/two-custom-campaign-ais-examples.8939/
function Int2Str takes integer ic returns string
    local string s = ""
    local integer i = ic
    local integer ialt = 0
    local boolean neg = false

    if i == 0 then
      return "0"
    endif
    if i < 0 then
      set neg = true
      set i = (-1)*i
    endif
    loop
      exitwhen i == 0
      set ialt = i
      set i = i / 10
      set s = Dig2Str( ialt - 10*i ) + s
    endloop
    if neg then
      set s = "-"+s
    endif
    return s
endfunction

function Event_OnHeroLevelGain takes nothing returns integer
    local integer DEVOTION_AURA = 1095262564
    local integer DIVINE_SHIELD = 1095263347
    local integer RESURRECTION	= 1095266917

	local integer iLevel		= GetHeroLevelAI()

	if 		iLevel == 1 then
		return HOLY_BOLT
	elseif	iLevel == 2 then
		return DEVOTION_AURA
	elseif 	iLevel == 3 then
		return HOLY_BOLT
	elseif	iLevel == 4 then
		return DIVINE_SHIELD
	elseif	iLevel == 5 then
		return HOLY_BOLT
	elseif	iLevel == 6 then
		return RESURRECTION
	elseif	iLevel == 7 then
		return DIVINE_SHIELD
	elseif	iLevel == 8 then
		return DEVOTION_AURA
	elseif	iLevel == 9 then
		return DEVOTION_AURA
	elseif	iLevel == 10 then
		return DIVINE_SHIELD
	endif

	return STAT_UP
endfunction

function InitAssaultGroup takes nothing returns nothing
	call InitAssault()

	call AddAssault(GetUnitCountDone(FOOTMAN) 	- IgnoredUnits(FOOTMAN)	, FOOTMAN	)
	call AddAssault(GetUnitCountDone(KNIGHT)	- IgnoredUnits(KNIGHT)	, KNIGHT	)
	call AddAssault(GetUnitCountDone(PRIEST)	- IgnoredUnits(PRIEST)	, PRIEST	)
	call AddAssault(GetUnitCountDone(UTHER)		- IgnoredUnits(UTHER)	, UTHER		)
endfunction

function FindFountainOfLive takes nothing returns nothing
	local integer	FOUNTAIN_OF_LIFE		= 1852206952
	local integer 	PLAYER_NEUTRAL_PASSIVE 	= 15

	local group 	hGroup 					= CreateGroup()
	local unit		hUnit

	call GroupEnumUnitsOfPlayer(hGroup, Player(PLAYER_NEUTRAL_PASSIVE), null)

	loop
		set hUnit = FirstOfGroup(hGroup)

		exitwhen hUnit == null

		if UnitAlive(hUnit) then
			if IsUnitType(hUnit, UNIT_TYPE_STRUCTURE) then
				if GetUnitTypeId(hUnit) == FOUNTAIN_OF_LIFE then
					set g_iFountainOfLifeX = R2I(GetWidgetX(hUnit)) + 200
					set g_iFountainOfLifeY = R2I(GetWidgetY(hUnit)) - 200

					exitwhen true
				endif
			endif
		endif

		call GroupRemoveUnit(hGroup, hUnit)
	endloop

	call DestroyGroup(hGroup)

	set hGroup 	= null
	set hUnit 	= null
endfunction

function ChangeCaptainHome takes nothing returns nothing
	local integer 	BOTH_CAPTAINS 	= 		3

	set 			g_iCaptainHomeX = 	-3700
	set 			g_iCaptainHomeY = 		0

	call SetCaptainHome(BOTH_CAPTAINS, g_iCaptainHomeX, g_iCaptainHomeY)
endfunction

function CreateUnits takes nothing returns nothing
	local integer MASK_OF_DEATH		= 1836016756
	local integer POTION_OF_HEALTH 	= 1885825125

	set g_hHero = 	CreateUnit(g_hPlayerAI, UTHER	, -1095	, -54	, 0)
    call 			CreateUnit(g_hPlayerAI, FOOTMAN	, -1302	, -722	, 0)
    call 			CreateUnit(g_hPlayerAI, FOOTMAN	, -1231	, -728	, 0)
    call 			CreateUnit(g_hPlayerAI, FOOTMAN	, -1154	, -730	, 0)
    call 			CreateUnit(g_hPlayerAI, FOOTMAN	, -1091	, -730	, 0)
    call 			CreateUnit(g_hPlayerAI, FOOTMAN	, -1014	, -730	, 0)
    call 			CreateUnit(g_hPlayerAI, FOOTMAN	, -951	, -728	, 0)
    call 			CreateUnit(g_hPlayerAI, FOOTMAN	, -858	, -722	, 0)
    call 			CreateUnit(g_hPlayerAI, FOOTMAN	, -918	, 257	, 0)
    call 			CreateUnit(g_hPlayerAI, FOOTMAN	, -1049	, 329	, 0)
    call 			CreateUnit(g_hPlayerAI, FOOTMAN	, -1118	, 374	, 0)
    call 			CreateUnit(g_hPlayerAI, FOOTMAN	, -982	, 295	, 0)
    call 			CreateUnit(g_hPlayerAI, KNIGHT	, -1099	, 106	, 0)
    call 			CreateUnit(g_hPlayerAI, KNIGHT	, -1234	, 5		, 0)
    call 			CreateUnit(g_hPlayerAI, PRIEST	, -1001	, -809	, 0)
    call 			CreateUnit(g_hPlayerAI, PRIEST	, -991	, -112	, 0)
    call 			CreateUnit(g_hPlayerAI, PRIEST	, -1152	, -818	, 0)
    call 			CreateUnit(g_hPlayerAI, PRIEST	, -1103	, -232	, 0)

    call UnitAddItemToSlotById(g_hHero, MASK_OF_DEATH	, 0)
    call UnitAddItemToSlotById(g_hHero, POTION_OF_HEALTH, 1)
endfunction

function IsEnemyInRangeXY takes integer iX, integer iY, integer iRadius returns boolean
	local boolean 	bIsFindEnemy 	= false
	local group 	hGroup 			= CreateGroup()
	local unit		hUnit

	call GroupEnumUnitsInRange(hGroup,iX, iY, I2R(iRadius), null)

	loop
		set hUnit = FirstOfGroup(hGroup)

		exitwhen hUnit == null

		if UnitAlive(hUnit) then
			if IsUnitEnemy(hUnit, g_hPlayerAI) then
				set bIsFindEnemy = true

				exitwhen true
			endif
		endif
	endloop

	call DestroyGroup(hGroup)

	set hGroup 	= null
	set hUnit	= null

	return bIsFindEnemy
endfunction

function CheckUnitHealth takes nothing returns nothing
	local integer	ORDER_SMART			= 851971
	local integer	ORDER_MOVE			= 851986
	local integer	MIN_SAFE_RANGE		= 200
	local integer	MIN_UNIT_HEALTH 	= 150

	local boolean	bIsUnitInHurtGroup

	local group 	hGroup 				= CreateGroup()

	local integer	iOffsetX
	local integer	iOffsetY

	local real 		flUnitHealth
	local unit 		hUnit

	call GroupEnumUnitsOfPlayer(hGroup, g_hPlayerAI, null)

	loop
		set hUnit = FirstOfGroup(hGroup)

		exitwhen hUnit == null

		set bIsUnitInHurtGroup = IsUnitInGroup(hUnit, g_hHurtUnitGroup)

		if UnitAlive(hUnit) then
			if not (IsUnitType(hUnit, UNIT_TYPE_SUMMONED) or hUnit == g_hHero) then
				set flUnitHealth = GetWidgetLife(hUnit)

				if 		R2I(flUnitHealth) < MIN_UNIT_HEALTH then
					set iOffsetX = GetRandomInt(-50, 50)
					set iOffsetY = GetRandomInt(-50, 50)
					call RemoveGuardPosition(hUnit)

					if not bIsUnitInHurtGroup then
						call GroupAddUnit(g_hHurtUnitGroup, hUnit)
					endif

					if IsEnemyInRangeXY(g_iFountainOfLifeX, g_iFountainOfLifeY, 1000) then
						if not IsUnitInRangeXY(hUnit, g_iCaptainHomeX, g_iCaptainHomeY, MIN_SAFE_RANGE) then
							call PrintToChat("Unit go home")

							call IssuePointOrderById(hUnit, ORDER_MOVE, g_iCaptainHomeX  + iOffsetX, g_iCaptainHomeY + iOffsetY)
						endif
					else
						if not IsUnitInRangeXY(hUnit, g_iFountainOfLifeX, g_iFountainOfLifeX, MIN_SAFE_RANGE) then
							call IssuePointOrderById(hUnit, ORDER_SMART	, g_iFountainOfLifeX + iOffsetX	, g_iFountainOfLifeY  + iOffsetY)
						endif
					endif
				elseif 	flUnitHealth * 1.5 > GetUnitState(hUnit, UNIT_STATE_MAX_LIFE) then
					if bIsUnitInHurtGroup then
						call PrintToChat("Unit back to captain control")

						call RecycleGuardPosition(hUnit)
						call GroupRemoveUnit(g_hHurtUnitGroup, hUnit)
					endif
				endif
			endif
		else
			if bIsUnitInHurtGroup then
				call GroupRemoveUnit(g_hHurtUnitGroup, hUnit)
			endif
		endif

		call GroupRemoveUnit(hGroup, hUnit)
	endloop

	if FirstOfGroup(g_hHurtUnitGroup) != null then	//NOTE: Some hurt units under attack at home
		if not CaptainIsHome() then
			if IsEnemyInRangeXY(g_iCaptainHomeX, g_iCaptainHomeY, MIN_SAFE_RANGE) then
				if not CaptainRetreating() then
					call ClearCaptainTargets()
					call CaptainGoHome()
					call SetGroupsFlee(true)	// NOTE: Tested
					call SetUnitsFlee(true)
				endif
			endif
		endif
	endif

	call DestroyGroup(hGroup)

	set hGroup 	= null
	set hUnit	= null
endfunction

function DevelopmentSequence takes nothing returns nothing
	loop
		call InitAssaultGroup()
		call CheckUnitHealth()
		call Sleep(DEFAULT_SLEEP)
	endloop
endfunction

function main takes nothing returns nothing
	set g_hPlayerAI = Player(GetAiPlayer())

	call SetHeroLevels(function Event_OnHeroLevelGain)

	call CreateUnits()

	call PrintToChat("AI Script started")

	call CreateCaptains()
	call GroupTimedLife(true)
	call SetCampaignAI()
	call SetHeroesFlee(true)
	call SetHeroesTakeItems(true)
	call SetWatchMegaTargets(true)

	call Sleep(0.1)
	call ChangeCaptainHome()

	call FindFountainOfLive()

	call StartThread(function DevelopmentSequence)

	loop
		call Sleep(1)
	endloop
endfunction
спасибо
32
Vitamin, ну такие ИИ же больше для мили, там микро не сделаешь... Лишь макро и тактика.
3
quq_CCCP:
Vitamin, ну такие ИИ же больше для мили, там микро не сделаешь... Лишь макро и тактика.
Не согласен с вами, если посмотреть тот же Advanced Melee AI это вполне реально, к тому же виртуальная машина под AI скрипты предоставляет достаточно много функций для написания того же микроконтроля
32
Vitamin, ну ок, пример кода - когда нужно юзать нестандартные предметы, прыг во врага и активация предмета стан по аое, ну или что аватар нужно врубать перед замесом а не лоу хп как это делает мили ИИ.
3
quq_CCCP:
Vitamin, ну ок, пример кода - когда нужно юзать нестандартные предметы, прыг во врага и активация предмета стан по аое, ну или что аватар нужно врубать перед замесом а не лоу хп как это делает мили ИИ.
Ну как то так (телепортация во врага и активация предмета я не сделал, но я не думаю, что это проблема будет для человека, который знает JASS)
AI Script
globals
	integer	g_iCaptainTimer	= 0
	player 	g_hPlayerAI 	= Player(GetAiPlayer())
	unit 	g_hHero
endglobals

function Event_OnHeroLevelGain takes nothing returns integer
	// NOTE: All hero levels and skills in this callback
	return 0
endfunction

function InitAssaultGroup takes nothing returns nothing
	local integer iHeroID 			= GetUnitTypeId(g_hHero)
	local integer iUnitInCaptain	= GetUnitCountDone(iHeroID) - IgnoredUnits(iHeroID)

	if iUnitInCaptain == 0 then
		return
	endif

	call InitAssault()
	call AddAssault(iUnitInCaptain, iHeroID)
endfunction

function FindHeroHandle takes nothing returns nothing
	local group hGroup = CreateGroup()
	local unit	hUnit

	call GroupEnumUnitsOfPlayer(hGroup, g_hPlayerAI, null)

	loop
		set hUnit = FirstOfGroup(hGroup)

		exitwhen hUnit == null

		if IsUnitType(hUnit, UNIT_TYPE_HERO) then	// NOTE: Only one hero available
			set g_hHero = hUnit
			exitwhen true
		endif

		call GroupRemoveUnit(hGroup, hUnit)
	endloop

	call DestroyGroup(hGroup)

	set hGroup 	= null
	set hUnit	= null
endfunction

function ApplyHeroItems takes nothing returns nothing
	local integer 	ITEM			= 'CODE'

	local integer 	iItemIndex		= 0
	local item		hItem

	loop
		exitwhen iItemIndex == 5

		set hItem = UnitItemInSlot(g_hHero, iItemIndex)

		if GetItemTypeId(hItem) == ITEM then
			exitwhen true
		endif

		set iItemIndex = iItemIndex + 1
	endloop

	if hItem == null then
		return
	endif

	// NOTE: Your conditions for applying item

	call UnitUseItem(g_hHero, hItem)
	// call UnitUseItemPoint
	// call UnitUseItemTarget
endfunction

function MonitoringHeroSkills takes nothing returns nothing
	// NOTE: Add check via Command or into AI Script if AI Hero using Avatar early and add global var for cooldown
	local integer AVATAR_ID				= 852086
	local integer MAX_CAPTAIN_ATTEMPTS 	= 5
	if not CaptainInCombat(true) then
		if g_iCaptainTimer != 0 then
			set g_iCaptainTimer = g_iCaptainTimer - 1
		endif
	else
		if g_iCaptainTimer == MAX_CAPTAIN_ATTEMPTS then
			call IssueImmediateOrderById(g_hHero, AVATAR_ID)
			set g_iCaptainTimer = 0
		else
			set g_iCaptainTimer = g_iCaptainTimer + 1
		endif
	endif
endfunction

function DevelopmentSequence takes nothing returns nothing
	loop
		call ApplyHeroItems()
		call MonitoringHeroSkills()
		call Sleep(1.0)
	endloop
endfunction

function main takes nothing returns nothing
	call SetHeroLevels(function Event_OnHeroLevelGain)

	call PrintToChat("AI Script started")

	call CreateCaptains()
	call GroupTimedLife(true)
	call SetCampaignAI()
	call SetHeroesFlee(true)
	call SetHeroesTakeItems(true)
	call SetWatchMegaTargets(true)

	call Sleep(0.1)

	call FindHeroHandle()

	call StartThread(function DevelopmentSequence)

	loop
		call InitAssaultGroup()
		call Sleep(1.0)
	endloop
endfunction
Если нужна полная кастомизация способности, то на основе способности канала делаем аватар и полностью пишем ИИ для способности соответсвенно
Плюс в AI скриптах тот, что они предоставляют функции управления капитанами, чего нету вне виртуальной машины AI скриптов (по крайней мере я знаю только это), соответсвенно функции SetProduce, GetCreepCamp и иные вне AI скриптов невозможны
А если что то надо связать из карты с AI скриптом, то тут благо есть функция CommandAI
32
Vitamin, не ну в потоке карты тоже реализовывали, правда там страшное кол-во кода.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.