27

» WarCraft 3 / Пиратка против лицензии.

ну мне нрав 1.26 как картоделу преимущественно из-за мемхака. просто хочется больше возможностей в новых патчей (они пока не радуют).

Reforged это конечно плюс. но что делать людям, которые вложились в множества моделей вара 3. кстати новое не всегда хорошо. есть ред алерт 2. ну устарела. но не потеряла интерес (щас red alert 2 online классные карты делает ore map, small map и defend president, морские сражения и др). вот ред алерт 3 там такая скука, че то не зашла. есть много примеров где старые части лучше а след части могут принести не то что ждешь.
27

» WarCraft 3 / Пиратка против лицензии.

совесть ваша будет чиста
по факту никакого. у меня раньше была 2 лицензионных диска. устанавливаешь, вводишь ключи. и можешь играть в battle.net с друзьями. лицензия принудительно автоматом обновляет патчи как жмешь кнопку battle net (можешь ненароком обновить не тот патч. вместо 1.26 тебе обновит 1.30. поэтому приходится качать патчи с инета. щас не знаю как. вроде минусов больше на новых патчах, есть конечно и плюсы новых патчей). Обычно можно сыграть по сетке спец прогой (не помню как называется. а точно гарена).
27

» WarCraft 3 / ChangeUnitModelTo после хекса, ветров и иллюзий

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
//==============
27

» WarCraft 3 / Как скрыть юнита локально?

на союзника используйте UnitShareVision
на врага применить иммунитет к детекту
код из хака
Обнаружение невидимых юнитов (все что связано с обзором и видимостью)
Есть близзардские boolean-нативки:
//IsUnitVisible - проверка: юнит видим ли игроком 
//IsUnitInvisible - проверка: невидим ли юнит для игрока
//IsItemVisible - проверка: итем видим
//IsLocationVisibleToPlayer или IsVisibleToPlayer - проверка видима ли точка игроком
//IsUnitDetected - юнит обнаружен игроком
все эти проверки выше "юнит видим ли игроком" и др не значат что юнит попал под обзор камеры игрока, и игрок видит в в данный момент. Нет это совсем другое. а то что игрок их может видеть)
"юнит обнаружен игроком" - это значит что попал под детектор игрока. А не в прямом смысле попал под обзор камеры игрока.

еще несколько близзардских нативок (действия):
UnitShareVision - поделиться/не делиться обзором юнита с другим игроком. Короче другой игрок видит, что делает чужой юнит. 
SetItemVisible - ShowUnit - ShowDestructable = спрятать или показать
далее код из хака
адреса флагов
    //достает адрес обнаружения юнита (это типа флага, что ваш юнит обнаружен)
    //кооперируется с другими offset-ами
    function GetUnitVisibilityClass takes unit u returns integer
        local integer a = ConvertHandle( u )
        local integer res = 0
        if a > 0 then
            set res = RMem( a + 0x130 )
            if res > 0 then
                set res = GetSomeAddressForAbility( res, RMem( a + 0x134 ) )
            endif
        endif
        return res
    endfunction

    //достает адрес обзора юнита (этот флаг показывает, с кем из игроков делит поле зрение)
    //кооперируется с другими offset-ами
    function GetUnitDetectedClass takes unit u returns integer
        local integer a = ConvertHandle( u )
        local integer res = 0
        if a > 0 then
            set res = RMem( a + 0x13C )
            if res > 0 then
                set res = GetSomeAddressForAbility( res, RMem( a + 0x140 ) )
            endif
        endif
        return res
    endfunction
проверка: делит ли юнит общий обзор с игроком
    //обычная проверка на видимость. 
    //помните: волшебный огонь у друида, он смотрит глазами врага, т.е. показывает то, что делает вражеский юнит на карте
    //еще такое можно добиться близардской функцией UnitShareVision
    function IsUnitDetectedByPlayer takes unit u, player p returns boolean
	//shared vision-like effect, used for Faerie fire / Wand of evil eye
	//have no reveal effect by itself, used only as detector?
        local integer a = GetUnitDetectedClass( u )
        if a > 0 then
            return IsFlagBitSet( RMem( a + 0x24 ), Player2Flag( p ) )
        endif
        return false
    endfunction
у игроков за видимость отвечают настройки союза. вот. обычно видит своих
вернуть/удалить детект
Проверял. Эта штука делает иммунным к детекту. Из-за этой херни много раз перепроверял. Короче кривовато работает. Иммунитет исчезает, если сам юнит или детекторы начнут двигаться относительно друг друга. Как только заново в поле зрение детектора попадаешь, то иммун сползает
    //Удалить детект с юнита (обнулить).
    //юнита u перестают обнаруживать вражеские детекторы
    function RemoveAnyDetectionFromUnit takes unit u returns nothing
        local integer a = ConvertHandle( u )
        if a > 0 then
            call WMem( a + 0x148, 0 )
            call WMem( a + 0x14C, 0 )
            set a = GetUnitVisibilityClass( u )
            if a > 0 then
                call WMem( a + 0x24, 0 )
            endif
        endif
    endfunction

   //Вернуть детект юниту
   //вашего юнита u могут обнаружить вражеские детекторы
    function RecountAnyDetectionForUnit takes unit u returns nothing
        local integer a = ConvertHandle( u )
        local integer sum = 0
        local integer i = 0
        if a > 0 then
            set a = GetUnitDetectedClass( u )
            if a > 0 then
                loop
                    if RMem( a + 0x2C + 4 * i ) > 0 then
                        set sum = sum + R2I( Pow( 2, i ) )
                    endif
                    set i = i + 1
                    exitwhen i > 15
                endloop
                call WMem( a + 0x14C, sum )
                call WMem( a + 0x148, sum )
                set sum = 0
                set i = 0
            endif
            set a = GetUnitVisibilityClass( u )
            if a > 0 then
                loop
                    if RMem( a + 0x2C + 4 * i ) > 0 then
                        set sum = sum + R2I( Pow( 2, i ) )
                    endif
                    set i = i + 1
                    exitwhen i > 15
                endloop
                call WMem( a + 0x24, sum )
            endif
        endif
    endfunction
Иммунитет к обнаружению инвизных
еще один похожий набор
//флаги москитов. За основу взят флаг москита. У москитов много флагов
    function GetSomeAddressForLocustFlags takes integer pAddr1 , integer pAddr2 returns integer
        local integer i = GetSomeAddress( pAddr1, pAddr2 )
        return RMem( i + 0x94 )
    endfunction

    function SetLocustFlags takes unit u, integer i returns nothing //These flags can make unit immune to truesight
        local integer pOff1
        set LastConvertedHandle = ConvertHandle( u )
        if LastConvertedHandle > 0 then
            set LastConvertedHandle = LastConvertedHandle + 0x16C
            set pOff1 = GetSomeAddressForLocustFlags( RMem( LastConvertedHandle ), RMem( LastConvertedHandle + 4 ) )
            if pOff1 > 0 then
                call WMem( pOff1 + 0x34, i )
            endif
        endif
    endfunction

    //Включить иммунитет к обнаружению инвизных юнитов
    //Это означает, что детекторы не смогут обнаружить невидимого юнита u
    function EnableTruesightImmunity takes unit u returns nothing
    //I don’t really know what other side effects may be caused by this, at least GroupEnum is not affected
    //Я не знаю, какие другие побочные эффекты могут быть вызваны этим, по крайней мере GroupEnum не влияет
        call SetLocustFlags( u, 0x08000000 )
    endfunction

	//Выключить иммунитет к обнаружению инвиза
    function DisableTruesightImmunity takes unit u returns nothing
        call SetLocustFlags( u, 0 )
    endfunction
27

» WarCraft 3 / Проверка на наличие юнитов рядом с областью

Принятый ответ
тебе надо что-то одно выбрать. а ты всунул одно и тоже в одну кучу, и выполняется действие это дважды (не верно).
код
в функции Trig_a_F записываются все условия, под которыми берут юнитов в группу
проверяем, что являются зданием. и что номера владельцев-игроков в диапазоне от 0 до 10. нумерация номеров начинается с 0. диапазон можно изменить.
function Trig_a_F takes nothing returns boolean
local integer n =GetPlayerId(GetOwningPlayer(GetFilterUnit()))
 return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)and(n>0 and n<10) 
endfunction
вводим условие Check(rect)
if Check(rect) then
ваши действия
endif
в функции основная фишка это проверять не пуст ли первый выбранный юнит в группе. с помощью FirstOfGroup. Если такого юнита нет (не записан в группе), выдаст null
function Check takes rect re returns boolean
local group g = CreateGroup() //создать группу
local real x = GetRectCenterX(re) //координаты центра области (x,y)
local real y = GetRectCenterY(re)
local boolean b
call GroupEnumUnitsInRange(g, x, y, 1600, Condition(function Trig_a_F))
set b = (FirstOfGroup(g)==null) //условие проверки: если первый попавшийся юнит пустой, запишет true. Иначе false
call DestroyGroup(g) //удаляем группу-утечку
set g = null //обнуляем
return b //вернет true (если группа пуста) или false (группа не пуста, значит есть какое поселение)
endfunction
27

» WarCraft 3 / Система рынка (продажа и покупка итемов)

14 версия

  • добавлена возможность магазину перелистывать списки итемов (можно вместить бесконечно число итемов)
  • добавлена отдельная сеть магазинов-обменников ресурсами (продаешь в одну торговую точку, появляется у остальных точек. покупаешь у одной, пропадают у всех)

В дальнейших планах:
  • попробовать реализовать торговлю между игроками. Что хочу сделать назначать ресурсы за итемов. Без хака нереально изменять ценник
  • использовать дабл-клик. повторную покупку таймером отслеживайте (проверяете сколько секунд прошло с первой покупкой.
Загруженные файлы
27

» WarCraft 3 / Проверка на наличие юнитов рядом с областью

Ну это просто:
если они спавнятся в центре области, а область перемещается периодически. Значит возьмем этот центр как основную точку. лучше конечно перемещать точку, чем рект. Но дело ваше
  1. проверять расстояние между осн точкой и центром поселения. Указываете сами опр дистанцию. если больше указанного расстояния, значит спавнить можно
  2. проверка. пикаете все здания игроков на карте. перебираете циклом каждое здание: чекаете расстояние между выбранным зданием и осн точкой. Если ни одно здание не попала в радиус, можно спавнить
  3. Заранее в вашем поселении на карте расставить области, объединить их в один регион. Лучше объединить в один, тк проще проверять будет. Это будет своего рода метка. И будешь проверять попала ли осн точка в регион или область (есть нативки).
27

» WarCraft 3 / Ошибочная проверка на жизнь

ArchOracle, возьми и раскрой BJ-обертки. внутри них лежат проверки хп>0 или хп<0 (is alive "юнит жив" хп>0, is dead "юнит мертв" хп<0). эти близзардские функции сравнивают хп. они не дают точно знать мертв ли сейчас (но должны, никогда не парился с этим), но по логике близзард хп равное 0 значит мертв
27

» WarCraft 3 / Ошибочная проверка на жизнь

ArchOracle, у тебя работает этот код (что выше)? если нет, выводи дебагом сколько у тебя хп в данный момент. Периодично раз 0.01-0.05 выводи на экран, меняется ли хп (если у тебя проверка хп. Просто интересно что происходит с хп героя).
UNIT_TYPE_DEAD - говорит что юнит мертв (лежащий трупак). Это всегда помогает.
сколько тем на форумах было на эти проверки, избитая проблема =(

не повышай тогда триггерно юниту, пока он мертв. Пробуй позже повышать.
27

» WarCraft 3 / Ошибочная проверка на жизнь

Принятый ответ
код
    //Определяет жив или мертв юнит. 
    //Есть точный параметр определения, что юнит мертв - UNIT_TYPE_DEAD
    //Если юнит удален или его труп разложился и исчез, то тип объекта IsUnitType обнуляется. Но переменные unit u все равно могут содержать инфу, варкрафт не обнуляет значения переменных.
    function IsUnitDead takes unit u returns boolean
        return IsUnitType( u, UNIT_TYPE_DEAD ) or GetUnitTypeId( u ) < 1
    endfunction
проверять хп не всегда хорошо. пользователи пишут что у них регенится хп, даже если юнит мертв (не сталкивался, не исключено). герои могут умереть, и трупы валяются на местах их смерти до сих пор пока не воскресят. еще есть случаи с крестом перерождения (но это отдельный случай)
function IsDead takes unit u returns boolean
	return GetWidgetLife(u) < 0.405 or IsUnitType(u,UNIT_TYPE_DEAD)
endfunction
27

» WarCraft 3 / Как терригенно купить дирижабль?

Принятый ответ
тема
пример возьмем еше этот пример, только здесь итем покупают. но можно переделать
27

» WarCraft 3 / Опыт для любого юнита (не героя)

тема про отряды ой не знаю, системы не смотрел. смотрите сами. в комментариях есть еще ссылки
27

» WarCraft 3 / Опыт для любого юнита (не героя)

можно сделать систему убийств. заводишь счетчик для каждого юнита. Можно на хэш-таблицу привязать, так можно и custom value, или массив переменной заюзать.
вот пример
27

» WarCraft 3 / Jass времён 1.24

в переменной не может быть ничего не записано. пример с целым числом либо вернет число. Если там ничего нет, то вернет 0. представь если пробовал манипулировать с несуществующим, то чего нет (крит игры если это объект). если return h ничего не может вернут, пробует return 0.
а так тебе сразу говорят 0 или null. единственная непонятная херня - это с конвертом, никак не могу понять как целое число заделывается в юнита. это получается хэндл возвращает?
27

» WarCraft 3 / Модель "Точки сбора"...

да зачем? ты модель заменить по указанному пути. разницы никакой не будет.
еще находил способности
AIfl, AIfn (Ночной эльф), AIfe (Нежить), AIfo (Орк), AIfm (Человек), AIfl (Орда)
UI\Feedback\RallyPoint\RallyPoint.mdl
Objects\InventoryItems\NightElfCaptureFlag\NightElfCaptureFlag.mdl
Objects\InventoryItems\UndeadCaptureFlag\UndeadCaptureFlag.mdl
Objects\InventoryItems\HumanCaptureFlag\HumanCaptureFlag.mdl
Objects\InventoryItems\BattleStandard\BattleStandard.mdl
Загруженные файлы
27

» WarCraft 3 / Синхронизация.

круто. только спецэффекты как помогут определять выделен или нет?
мне кажется оставить как есть (не надо юнитам одним и тем же коррдинаты разные задавать разным локал машинам), только нужно визуально скрыть. А проверять что нажата кнопка (выделена) только нужные опред игроком.
не получится одному и тому же юниту на разных машинах разные координаты задать. это приводит у десинхрону
27

» WarCraft 3 / Модель "Точки сбора"...

эх лентяи. взял бы mpq-архиватор и пошел искать Rally-Point. ну ладно, я бы тоже не знал бы что искать, не зная англ. название точки сбора. по jass помню
UI/Feedback/RallyPoint <= в этой папке лежат модели от разных рас, и текстуры +тимколор
UI/Feedback/RallyPoint/RallyPoint.mdx
UI/Feedback/RallyPoint/OrcRallyFlag.mdx
UI/Feedback/RallyPoint/NightElfRallyFlag.mdx
UI/Feedback/RallyPoint/UndeadRallyFlag.mdx
27

» WarCraft 3 / Локальный ресурс

смотря что ты хочешь сделать.

вот например, если надо чтобы каждый игрок видел в магазине своих юнитов (орк орочьих, хуман хуманских), то можно было попробовать. недавно проверял, несколько месяцев. там в магазине есть найм и есть тренировка. отличаются друг от друга. тренировка (можно лимитировать, каждый игрок может задать свой лимит, и даже прятать лимитом иконку. задаешь через shift кучу типов в ро (орков хуманов и тд), прячешь одному одних, второму других и тд. недостаток: видит этих юнитов только владелец бараков, и только он их может заказать). покупка (найм) не имеет таких возможностей как задать лимит и прочее, нет нативок (если не путаю). пробовал через GetLocalPlayer на каждого игрока создать свой id-unit в магазине. это и вправду каждый видит своих в магазине, но как только купишь, то приведет к десихрону. тк создается юнит у каждого свой.
правда в статье дока упоминалось создание разных типов как в карте мафии (если не вызывать проверки на типы), почему нет там конфликтов.

изменять иконки и описания например итемов или юнитов не получится в патче 1.26. нет таких прямых нативок. только в мемхаке. кстати, изменить описание можно только типу, а не конкретному объекту (вот конкретному можно ли изменить? это не знаю). если меняешь одному, меняешь всем такого же типа. возможно тут на каждого игрока создавать свой тип с другим описанием и иконой.
иконки еще не пробовал в мемхаке менять
жди спецов по этим вопросам

мб как-то можно нестандартные сделать. но это будет сложный изврат
27

» WarCraft 3 / Тест на десинк.

ссылка нужно запустить две виртуальные мишины (или иначе говоря два варкрафта). Там где есть проблемный код с GetLocalPlayer() или похожие (но чаще проблемы из-за LocalPlayer), проверяешь. запускаешь два варкрафта, запускаешь код в игре. Если вылетает, значит, код неприемлемый. См. статью Дока. еще дохрена задавали вопросов похожих и варианты обсосали
27

» WarCraft 3 / можно ли скрыть счетчик у работника лентяя?

код от Драколича
//Является ли юнит неактивным (находится ли он в состоянии покоя или нет)
    //В некоторых случаях полезна знать стоит ли юнит, т.к. ловить приказ не надежно
    function IsUnitUnactive takes unit u returns boolean
        set LastConvertedHandle = ConvertHandle( u )
        if LastConvertedHandle > 0 then
            return (RMem(LastConvertedHandle+0x174)==-1)
        endif
        return false
    endfunction
27

» Commander! Blue Alert / Герои СССР: Гепон и Настя.

ред алерт 2 нрав. но когда в это поиграть можно будет?

этот ролик смешной, пародия на видеозаставки в ред алерт 2