32

» WarCraft 3 / Как сделать стакающиеся атаки?

Пассивка повелителя огня в помощь, раз уж такие вопросы. Кастомная реализация без багов весьма сложная без вспомогательных средств вроде UJAPI или мемхака.
32

» WarCraft 3 / Патч игры

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

» WarCraft 3 / Какие ошибки допущены в данной способности? Jass.

Ну во первых вовсе нифига не цепная молния, алгоритм даже не близко. Во вторых на кой черт ты и двигаешь молнии и находишь цели с 1 таймером, усложнил код и ниче не работает в итоге.
Отдельный код должен двигать молнию, отдельный искать цели и добавлять между ними разряды молний.
Стандартная молния ищет ближайшего видимого противника, к слову были же системы движения молний на сайте? Не?
Ниже кусок кода продвинутой дотки 6.83, цепная молния 1 в 1 как дефолт:
function Timer_ArcBolt_Expired takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer id = GetHandleId( t )
    local unit cast = LoadUnitHandle( HashData, id, 0 )
    local unit targ = LoadUnitHandle( HashData, id, 1 )
    local integer max = LoadInteger( HashData, id, 4 )
    local integer cur = LoadInteger( HashData, id, 5 )
    local group grp = LoadGroupHandle( HashData, id, ExChainGroup )
    local unit enemy = null

    call UnitDamageTarget( cast, targ, LoadReal( HashData, id, 3 ), false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS )
    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\Bolt\\BoltImpact.mdl", targ, "chest" ) )

    call GroupAddUnit( grp, targ )
    call GroupClear( bj_TempGroup )
    set bj_groupEnumOwningPlayer = GetOwningPlayer( cast )
    set bj_ChainGroup = grp
    call GroupEnumUnitsInRange( bj_TempGroup, GetUnitX( targ ), GetUnitY( targ ), RMaxBJ( LoadReal( HashData, id, 6 ), 200.00 ), Condition( function Only_Visibly_Enemy_No_Immune_NoReply_Unit ) )
    call GroupRemoveUnit( bj_TempGroup, targ )
    set enemy = GroupPickRandomUnit( bj_TempGroup )

    if enemy == null or cur >= max then
        call PauseTimer( t )
        call ReleaseTimer( t )
        call FlushChildHashtable( HashData, id )
        call NSI( grp )
    else
        call SaveInteger( HashData, id, 5, cur + 1 )
        call SaveUnitHandle( HashData, id, 1, enemy )
        call CreateBolt( targ, enemy, "CLSB", 1.50, false )
    endif

    set cast = null
    set targ = null
    set enemy = null
    set grp = null
    set t = null
endfunction

function Trig_ArcLightning_Actions takes nothing returns nothing
    local unit cast = GetSpellAbilityUnit( )
    local unit targ = GetSpellTargetUnit( )
    local integer level = GetUnitAbilityLevel( cast, 'A020' )
    local integer max = 3 + 2 * level
    local timer t = NewTimer( )
    local integer id = GetHandleId( t )

    if level == 4 then
        set max = 15
    endif

    call SaveUnitHandle( HashData, id, 0, cast )
    call SaveUnitHandle( HashData, id, 1, targ )
    call SaveReal( HashData, id, 3, 50.00 + 30.00 * level )
    call SaveInteger( HashData, id, 4, max )
    call SaveInteger( HashData, id, 5, 1 )
    call SaveGroupHandle( HashData, id, ExChainGroup, NTI( ) )
    call SaveReal( HashData, id, 6, 525 )

    call CreateBolt( cast, targ, "CLPB", 1.50, true )

    call TimerStart( t, 0.25, true, function Timer_ArcBolt_Expired )

    set cast = null
    set targ = null
    set t = null
endfunction

function Trig_ArcLightning_Conditions takes nothing returns boolean
    if GetSpellAbilityId( ) == 'A020' and not IsUnitHasNegation( GetSpellTargetUnit( ) ) then
        call Trig_ArcLightning_Actions( )
    endif
    return false
endfunction

//==== Init Trigger NewTrigger ====
function InitTrig_ArcLightning takes nothing returns nothing
    local trigger trg = CreateTrigger( )
    local integer nIndex = 1

    call TriggerAddCondition( trg, Condition( function Trig_ArcLightning_Conditions ) )

    loop
        exitwhen nIndex > 11
        if IsSlotPlayer( Player( nIndex ) ) then
            call TriggerRegisterPlayerUnitEvent( trg, Player( nIndex ), EVENT_PLAYER_UNIT_SPELL_EFFECT, OnlyHero )
        endif
        set nIndex = nIndex + 1
    endloop

    set trg = null
endfunction

пример поиска ближайшего юнита:
function AQ1 takes nothing returns nothing
    local unit enum = GetEnumUnit( )
    local real d = DistBetweenCords( GetUnitX( enum ), GetUnitY( enum ), PJ, QJ )
    if d < RJ then
        set RJ = d
        set TJ = enum
    endif
    set enum = null
endfunction

function AU1 takes group g, real x, real y returns unit
    set RJ = 999999
    set TJ = null
    set PJ = x
    set QJ = y
    call ForGroup( g, function AQ1 )
    return TJ
endfunction

Ну а вот урезанный кусок от системы движения молний, собственно чтобы делать красивые молниии нужно еще знать ImpactZ, это либо бд либо мемхак.
	struct LightningData
    private static constant timer period = CreateTimer( )
    private thistype prev
    private thistype next
    private lightning bolt
    private unit a1
    private unit a2
    private real ax1
    private real ay1
    private real ax2
    private real ay2
    private real alpha
    private real ticks
    private real time
    private boolean flag


    private stub method destroy takes nothing returns nothing

    call SetLightningColor( this.bolt, 0.00, 0.00, 0.00, 0.00 )
    call DestroyLightning( this.bolt )
    set this.a1 = null
    set this.a2 = null
    set this.bolt = null
    set this.alpha = 0.00

    set this.prev.next = this.next
    set this.next.prev = this.prev

    if ( thistype( 0 ).next == 0 ) then
        call PauseTimer( thistype.period )
    endif

    call thistype.deallocate( this )
endmethod
        
private static method iterate takes nothing returns nothing
    local thistype this = thistype( 0 ).next

    loop
        exitwhen ( this == 0 )
                
        if not IsUnitDead( this.a1 ) then
            set this.ax1 = GetUnitX( this.a1 )
            set this.ay1 = GetUnitY( this.a1 )
            if this.flag then
                set this.ax1 = this.ax1 + 25.00
                set this.ay1 = this.ay1 - 25.00
            endif
        endif
                    
        if not IsUnitDead( this.a2 ) then
            set this.ax2 = GetUnitX( this.a2 )
            set this.ay2 = GetUnitY( this.a2 )
        endif
                
        set TempAZ = GetLocationZ( bj_TempPoint ) + GetUnitFlyHeight( this.a1 ) + GetUnitHeight( this.a1 )
        call MoveLocation( bj_TempPoint, this.ax2, this.ay2 )
        set TempBZ = GetLocationZ( bj_TempPoint ) + GetUnitFlyHeight( this.a2 ) + GetUnitHeight( this.a2 )
        call MoveLightningEx( this.bolt, true, this.ax1, this.ay1, TempAZ, this.ax2, this.ay2, TempBZ )
                    
        if GetLightningColorA( this.bolt ) > this.alpha then
            call SetLightningColor( this.bolt, GetLightningColorR( this.bolt ), GetLightningColorG( this.bolt ), GetLightningColorB( this.bolt ), GetLightningColorA( this.bolt ) - this.alpha )
        endif
                    
        set this.ticks = ( this.ticks + 0.03125 ) * 1.00
        if this.ticks > this.time then
            call this.destroy( )
        endif
                    
        set this = this.next
    endloop

endmethod

static method CreateBolt takes unit a, unit b, string CodeName, real timeout, boolean IsCaster returns thistype
    local thistype this = thistype.allocate( )

    set this.next = thistype( 0 )
    set this.prev = thistype( 0 ).prev
    set this.next.prev = this
    set this.prev.next = this
    set this.a1 = a
    set this.a2 = b
    set this.ax1 = GetUnitX( this.a1 )
    set this.ay1 = GetUnitY( this.a1 )
    set this.ax2 = GetUnitX( this.a2 )
    set this.ay2 = GetUnitY( this.a2 )
    set this.alpha = ( 1.00 / ( timeout / 0.03125 ) )
    set this.ticks = 0
    set this.time = timeout
    set this.flag = IsCaster
            
    call MoveLocation( bj_TempPoint, this.ax1, this.ay1 )
    set TempAZ = GetLocationZ( bj_TempPoint ) + GetUnitFlyHeight( this.a1 ) + GetUnitHeight( this.a1 )
    call MoveLocation( bj_TempPoint, this.ax2, this.ay2 )
    set TempBZ = GetLocationZ( bj_TempPoint ) + GetUnitFlyHeight( this.a2 ) + GetUnitHeight( this.a2 )
    if this.flag then
        set this.ax1 = this.ax1 + 25.00
        set this.ay1 = this.ay1 - 25.00
    endif
    set this.bolt = AddLightningEx( CodeName, true, this.ax1, this.ay1, TempAZ, this.ax2, this.ay2, TempBZ )
    if ( this.prev == 0 ) then
        call TimerStart( thistype.period, 0.03125, true, function thistype.iterate )
    endif
    return this
endmethod
endstruct
32

» WarCraft 3 / Снижение брони за атаку

А тебе ненужно отслеживать применение, тебе нужно отслеживать урон выше 0 и появление баффа стрел в статусе.
32

» WarCraft 3 / Не работает триггер

Во первых куча утечек, во вторых нормальный фильтр сделай и проверку что юнит то есть, в третих а даммик то видит цель? Может кинуть спелл?
32

» WarCraft 3 / Формула получения exp

Ну вот примерная функция:
function aow_GetApxExpBounty takes unit u returns real
return SquareRoot((GetUnitState(u, UNIT_STATE_MAX_LIFE) + GetUnitState(u, UNIT_STATE_MAX_MANA)) * GetUnitLevel(u)) * 2
endfunction
Ну в целом там куда более сложный код, там идет разделение по расстоянию и прочее.
32

» WarCraft 3 / Как сделать выбор героев через таверну как в доте

Ну а чем плох выбор героя в тавернах? Ну и почему именно фреймы? Вот хз, если честно, да раньше было нельзя так сделать а щяс можно - но зачем? Выбор героев только как не делали, двойным кликов - Конфетные войны 2004, трекабли + кинематик (гранпри азерота), таверны, светлячки, ой а вспоминаю древние карты года 2006 по вахе, там трекабли были и лок камеры. Ну там всякие настройки делали как в Pimp My Peon дамми гером, или рабочим. И как то особо это не считалось, до доты даже не дошло, хотя техническая возможность была еще тогда.
32

» WarCraft 3 / Включить ИИ для игрока-человека

Принятый ответ
Никак не включить, это взаимоисключающие параметры - живой игрок и ИИ.
Для помощи, пишем свои скрипты.

Микро контроль стандартных ИИ зашит в Game.dll и ваще никак с уровня ИИ скрипта для сражений не управляется, все эти подшаги и атака огненной стрелой жрицы луны, хил паладина в юнита на 10 хп, или выбор позиции для здания - ни управляется никак, оно тупо есть, как и все шаблоны кастов для нейтралов. Так что пишите своё собственное.
32

» WarCraft 3 / Движущийся закопавшийся и нырнувший

Разумеется, потому что модель надо другую делать, у тебя одна и та же модель, в которой нет анимации плаванья \ ползанья под землей.

Нужно делать кастом модель с анимацией, и полупрозрачным силуеэтом (лужей) чтобы при детекте было понятно кто там и что там.
32

» WarCraft 3 / Запрет выбора юнита

RvunOchka, а что тут непонятно, вручаешь юнитам невидимость, и настраиваешь аспект союза с общим обзором, и юнит становится не видимым для союзника.
32

» WarCraft 3 / Запрет выбора юнита

Инвизы, просто настраиваем аспекты союзов, юниты невидимые и всё.
32

» WarCraft 3 / Как использовать тип ability? Jass. MemoryHack.

Принятый ответ
LastUchiha, да, GetUnitAbility для получения адреса pAbil, и всё. Адресс всю игру у одного юнита будет один и тот же, поэтому адресс абилки можно сохранять в хештаблицу к примеру.
32

» WarCraft 3 / Как использовать тип ability? Jass. MemoryHack.

LastUchiha, есть, не так выглядят, там есть для абилки и для адреса, тебе нужны для адреса.
32

» WarCraft 3 / Как использовать тип ability? Jass. MemoryHack.

Снова схватил что попало не глядя, тебе нужен указатель на абилку - это integer, в мемхаке есть функция GetUnitAbility( unit, integer id) returns integer
Обязательно проверять на наличиее абилки и чему равен указатель, если он меньше 1 то абилки у юнита нету.

function ShowAbilityById_Main takes integer ConvertedHandle, integer d returns nothing
	if ConvertedHandle>0 and RMem(ConvertedHandle)>0 then
		call WMem(ConvertedHandle + 0x40,RMem(ConvertedHandle + 0x40)+d)
	endif
endfunction

function HideAbilityButton takes unit u, integer id, boolean hide returns nothing
	local integer offset
	if u!=null and id!=0 then
		set offset=GetUnitAbility(u,id)
		if offset!=0 then
			if hide then
				call ShowAbilityById_Main(offset,1)
			else
				call ShowAbilityById_Main(offset,-1)
			endif
		endif
	endif
endfunction
Все просто, находишь у юнита указатель на абилку, если он не равен нулю, то записываешь в адрес абилки +0x40 значение, любое выше 0 это абилка скрыта, это счетчик.
Внимательно смотри на список функций, там наделаны на все случаи жизни, выбирай не первую попавшуюся.
32

» WarCraft 3 / нужен эффект ауры аганима для карты iccup dota

Ну нужен так пусть делают разработчики айкап доты, они же там вроде как работаю не за спасибо (но это неточно).
Потом в какую из их доток, у них их 2.

Ах да, и какую такую ауру, у аганима же ауры нету? Не?
32

» WarCraft 3 / Повелитель Могил

У него анимации закопки, выкопки и атаки из под земли сделаны для ролика в кампании нежити. Там Анубарак всегда из подземли вылазит.
32

» WarCraft 3 / Фаталит функция из мемхака. Jass

LastUchiha, я бы взял мемхак 1.6 к примеру и перенес, хз правда для чего именно он вам нужен. но откуда код функции выше?
Во первых нет определения версии игры, во вторых проверки входных аргументов, в теме с мемхаком обсуждалось раз 10.
Не все выложенные функции - рабочие, многие демонстрационные и не годятся для игровых карт из за изьянов.
32

» WarCraft 3 / Фаталит функция из мемхака. Jass

LastUchiha, это не проблема а чепуха какая то, все одно и то же, просто думаем головой.
32

» WarCraft 3 / Фаталит функция из мемхака. Jass

Принятый ответ
Как насчет юзать её нормальную версию из новых сборок мемхака?

function StartAbilityCooldown takes unit whichUnit, integer abilityId, real cd returns boolean
    local integer pAbility = 0
    local integer offset1
    local integer offset2
    local boolean bRes = false
    if GetUnitAbilityLevel( whichUnit, abilityId ) == 0 or cd == 0.00 then
        return bRes
    endif
    set pAbility = GetUnitAbility( whichUnit, abilityId )
    if pAbility < 1 then
        return bRes
    else
        set offset1 = RMem( pAbility + 0x134 )
        set offset2 = RMem( pAbility + 0x138 )
        if offset1 > 0 or offset1 < 0 or offset2 > 0 or offset2 < 0 then
            call WMem( pAbility + 0x134, mR2I( cd ) )
            call WMem( pAbility + 0x138, mR2I( 10.00 ) )
        endif
        set Memory[pReserverdIntArg1 / 4] = mR2I( cd )
        call CallThisCallWith2Args( pStartAbilityCD, pAbility, pReserverdIntArg1 )
        set bRes = IsAbilityOnCooldown( pAbility )
        call WMem( pAbility + 0x134, offset1 )
        call WMem( pAbility + 0x138, offset2 )
    endif
    return bRes
endfunction

Либо
function StartAbilityCooldown takes unit whichUnit, integer abilityId, real cd returns boolean
local integer pAbility = 0
local boolean bRes = false
if GetUnitAbilityLevel( whichUnit, abilityId ) == 0 or cd == 0.00 then
    return bRes
endif

set pAbility = GetUnitAbility( whichUnit, abilityId )
if pAbility < 1 then
    return bRes
else
    call WMem(pReservedIntArg1 , SetRealIntoMemory(cd))
    call this_call_2(pStartAbilityCD , pAbility , pReservedIntArg1)
    set bRes = IsAbilityOnCooldown(pAbility)
endif
return bRes
32

» WarCraft 3 / Наложение спецэффектов от юнита к юниту

Принятый ответ
Можно, рисовать молнию, есть куча функций для работы с молниями, создание, движение, изменение цвета и прозрачности. Не хватает только GetUnitImpactZ
Но это поправимо базой данных или Мемхаком.
32

» WarCraft 3 / SimulateAttackInstance работает?

Принятый ответ
Работает, код нужно поправить. В цель летит тычка, как от атаки, но событие атаки не срабатывает. Криты пашут как и орбы.

Так же можно CastAbilityTarget кидать огненные или ядовитые стрелы, эффект почти тот же, но уже с атакой.

function SimulateAttackInstance takes unit u, unit target returns nothing
	local integer a=GetUnitAbility(u,'Aatk')
	local integer b
	if a>0 then
		set b=ConvertHandle(target)
		//call BJDebugMsg("attack starting")
		call CallThisCallWith7Args(pSimulateAttackInstance,a,b,0,0,1,1,1)
		//attack ability
		//target
		//unknown, must be zero in order to attack to happen
		//1 if should use orb-modifier (any)
		//unused
		//unknown
		//unknown
		//0 1 0 0 0 - autocast hotkey OR searing arrow passive cast (orb of slow, geminate attack)
		//0 0 1 1 1 - default attack
		//0 0 1 0 0 - attack with orb-effect (2nd index?)
		
	endif
endfunction
pSimulateAttackInstance - это указатель на функцию в Game.Dll
На 1.26а он вот такой - set pSimulateAttackInstance = GameDLL + 0xCF660
на другие патчи, никто не искал.
У того кто атакует должна быть Aatk - способность атаковать, целью является виджет, которая должна быть не null, виджетом, который уязвим.
В целом функция демонстрационная, не развивалась и в конечные сборки мемхаков не попала.
32

» WarCraft 3 / Способность Celestial Hammer из Доты 2

Extremator, что в плане алгоритма что в плане кода, рекс 2 таймера, 2 даммика, которые летят по эллипсу, для каждого свой... Ну и в целом алгоритм убог, примеры были на сайте из того же пудж варс с более продвинутой математикой.