В общем смена модели багуется и возвращает дефолтную модель, пока вижу только 1 костыльный вариант, по поводу восстановление изменённой модели, отлавливать суммон иллюзий, отлавливать когда закончиться хекс, отлавливать когда приземлится с ветров... но может и ещё больше костылей придётся писать и я ещё не всё заметил.
Есть ли какая-то альтернатива?

если у тебя один юнит такого рода, то проще менять одновременно и в данных модель для этого типа юнитов
function SetUnitModelUF takes unit u, string s returns nothing
call SetUnitModel(GetUnitUIDefByIdCaching(GetUnitTypeId(u)),s)
endfunction
а иначе отлавливать события получения 0 урона и проверять, что если юнит под хексом или ветрами - то перерисовывать модель, для чего проще всего сделать эти хексы и ветра от лица дамми, чтоб знать наверняка.
`
ОЖИДАНИЕ РЕКЛАМЫ...
16
если у тебя один юнит такого рода, то проще менять одновременно и в данных модель для этого типа юнитов
function SetUnitModelUF takes unit u, string s returns nothing
call SetUnitModel(GetUnitUIDefByIdCaching(GetUnitTypeId(u)),s)
endfunction
а иначе отлавливать события получения 0 урона и проверять, что если юнит под хексом или ветрами - то перерисовывать модель, для чего проще всего сделать эти хексы и ветра от лица дамми, чтоб знать наверняка.
Принятый ответ
33
спасибо за SetUnitModelUF, понял что делает, но мне не подойдёт, у меня один юнит принимает 5 состояний через смену модели, буду отлавливать хексы с ветрами, делать нечего..
27
Bergi_Bear, вот что делает
код
//модель юнита
    //конвентирует тип юнита id (где id - равкод) в строку, где записан путь модели указанного типа
    function GetUnitModelPath takes integer id returns string
        local integer k=GetUnitUIDefByIdCaching(id)
        if k < 1 then
            return null
        endif
        set k=k+0x30
        if RMem(k)>0 then
            return ConvertNullTerminatedStringToString(RMem(k))
        endif
        return null
    endfunction
    
    //---изменить модель юнита, где uiobjectaddr - адрес типа юнит. 
    //берем адрес юнита типа юнита GetUnitUIDefByIdCaching. Если изменяешь значение типа юнита, то распространяются изменения на всех юнитов.
    //Примечание: изменение не распространяется на созданных юнитах, только на новых юнитах (например если вызвать иллюзии, то у двоиников будут новые модели. Или создать новых)
    //Нужно вызвать функцию перерисовки юнита. иначе в базе данных юнита указана новая модель, но у самого юнита модель не изменилась 
    function SetUnitModel takes integer uiobjectaddr, string s returns nothing
        call WriteNullTerminatedString( s, uiobjectaddr + 0x30 )
    endfunction
    //---В качестве аргумента выступает юнит. Изменяет модель типа юнита.
    function SetUnitModelUF takes unit u, string s returns nothing//user-friendly
		call SetUnitModel(GetUnitUIDefByIdCaching(GetUnitTypeId(u)),s)
	endfunction
    //---Адрес.
    function SetUnitModelUFAddress takes integer address, string s returns nothing
        call SetUnitModel( address, s )
    endfunction
    
    //вот функция смены модели (прорисовки модели)
    //Примечание: изменение распространяется на текущего юнита, (например если вызвать иллюзии, то у двоиников НЕ БУДУТ новые модели)
    function ChangeUnitModelTo takes unit u, string modelpath returns nothing
	local integer a
	local integer s
	set LastConvertedHandle=ConvertHandle(u)
	if LastConvertedHandle>0 then
		set a=RMem(LastConvertedHandle)+0x88
		if a>0 then
			set a=RMem(a)
			if a>0 then
				set s=GetStringAddress(modelpath)
				call CallThisCallWith3Args(a,LastConvertedHandle,s,1)
			endif
		endif
	endif
    endfunction
    
//====================


//Модель портрета
    //----Узнать путь портрета указанного типа юнита (id - rawcode юнита)
    //Изменение распространяется на тип, это значит, распространяется на всех юнитов двнного типа
    function GetUnitModelPortrait takes integer id returns string
        local integer k=GetUnitUIDefByIdCaching(id)
        if k < 1 then
            return null
        endif
        set k=k+0x34
        if RMem(k)>0 then
			return ConvertNullTerminatedStringToString(RMem(k))
        endif
        return null
    endfunction
    //----Изменить путь портрета указанного типа юнита (uiobjectaddr - адрес указанного типа юнита)
    function SetUnitPortrait takes integer uiobjectaddr, string s returns nothing
        call AddNewOffsetToRestoreFast(uiobjectaddr+0x34)
        call WMem(uiobjectaddr+0x34, GetStringAddress(s))
    endfunction
    //----Изменить путь портрета указанного типа юнита (id - rawcode юнита)
    function SetUnitPortraitById takes integer id, string s returns nothing
        call SetUnitPortrait(GetUnitUIDefByIdCaching(id),s)
    endfunction    
//===============

//Перерисовка модели юнита, вроде обновляет прекрепленные эффекты с помощью триггеров.
    function RedrawUnit takes unit u returns nothing
		local integer LastConvertedHandle=ConvertHandle(u)
		if LastConvertedHandle>0 then
			call CallThisCallWith1Args(pRedrawUnitFunction,LastConvertedHandle)
		endif
	endfunction
//==============
33
Steal nerves, Смотрю вы подробно разобрались, но я вот так и не понял что надо указать в качестве uiobjectaddr , что ещё за адрес юнита? Можно пример использования?
27
обычно у разных объектов разные адреса, и соответственно и разные функции нахождения адресов.

адрес на конкретного юнита, итема, декора и др короче объект хэндл ConvertHandle. см пример функции SetUnitModelUFAddress. есть функции которые возвращают адрес, или требуют адрес. да и большая часть кода в мемхаке требует ConvertHandle
пример
    //Выдает адрес выделенного юнита, панель интерфейса, которая отображена на экране у локального игрока
    //допустим выделив рамкой 2 юнитов: героя и раба, у вас будет отображаться в окне посерединке 2 иконки выделенных юнитов. Но сбоку меню будет переключено на героя (механика вара)
    //если взять нажать Tab, можно переключать меню на другого юнита, так с героя на раба
    //так этой функции можно было узнать какой юнит нажал кнопку строить, или если контроль за юнитом расшарен между игроками можно узнать кто из игроков отдал приказ (или купил)
    function GetActiveUnitInSelection takes nothing returns integer
        return RMem(pGameUICurrentSelection+0x238)
    endfunction

адрес на тип uiobjectaddr GetUnitUIDefByIdCaching(id-rawcode ). см пример функции SetUnitModelUF.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.