nik5960nik, даже если не удалён но сдох - это повод ничего с юнитом не делать, вручение источника ауры дохлому = фатал, изменение уровня абилки = фатал, изменение статов - бага с бонусами от статов. Допом проверяем на GetHandleId()
нужно проверять на UNIT_TYPE_DEAD или на флаги в мемхаке, тогда отловите удаленных, ему флаг вручают, после чего юнит утилизируется движком - ссылки на него при этом будут не равны null, так же проверяйте на HandleId() если меньше 1, хендл некорректный.
В голову лезет хак, на нажатие автоматом отмены...
Еще бесит что на ракапе если игра закончилась и все вышли а ты по каким то причинам задержался, бот почему то думает что игроки потеряли соединение и пытается их рекконектить, вот это дело бы сломать, но чет пока никто не сделал.
Пассивка повелителя огня в помощь, раз уж такие вопросы. Кастомная реализация без багов весьма сложная без вспомогательных средств вроде UJAPI или мемхака.
Если карта после протектора особо не узнаешь, а так в скрипте и файле имен прямо пишется версия игры на которой карта создана и дата, ну и по хорошему карта должна игратся на патче на котором она создана. Мили карты в теории без проблем запустятся на более старших патчах, а вот кастомки - а как повезёт.
Ну во первых вовсе нифига не цепная молния, алгоритм даже не близко. Во вторых на кой черт ты и двигаешь молнии и находишь цели с 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
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
Ну в целом там куда более сложный код, там идет разделение по расстоянию и прочее.
Ну а чем плох выбор героя в тавернах? Ну и почему именно фреймы? Вот хз, если честно, да раньше было нельзя так сделать а щяс можно - но зачем? Выбор героев только как не делали, двойным кликов - Конфетные войны 2004, трекабли + кинематик (гранпри азерота), таверны, светлячки, ой а вспоминаю древние карты года 2006 по вахе, там трекабли были и лок камеры. Ну там всякие настройки делали как в Pimp My Peon дамми гером, или рабочим. И как то особо это не считалось, до доты даже не дошло, хотя техническая возможность была еще тогда.
Никак не включить, это взаимоисключающие параметры - живой игрок и ИИ.
Для помощи, пишем свои скрипты.
Микро контроль стандартных ИИ зашит в Game.dll и ваще никак с уровня ИИ скрипта для сражений не управляется, все эти подшаги и атака огненной стрелой жрицы луны, хил паладина в юнита на 10 хп, или выбор позиции для здания - ни управляется никак, оно тупо есть, как и все шаблоны кастов для нейтралов. Так что пишите своё собственное.
LastUchiha, да, GetUnitAbility для получения адреса pAbil, и всё. Адресс всю игру у одного юнита будет один и тот же, поэтому адресс абилки можно сохранять в хештаблицу к примеру.
Снова схватил что попало не глядя, тебе нужен указатель на абилку - это 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 это абилка скрыта, это счетчик.
Внимательно смотри на список функций, там наделаны на все случаи жизни, выбирай не первую попавшуюся.
» WarCraft 3 / Проверка на удаленного юнита
» WarCraft 3 / Проверка на удаленного юнита
» WarCraft 3 / Что изменить в mpq чтоб грохнуть диалоги
Еще бесит что на ракапе если игра закончилась и все вышли а ты по каким то причинам задержался, бот почему то думает что игроки потеряли соединение и пытается их рекконектить, вот это дело бы сломать, но чет пока никто не сделал.
» WarCraft 3 / Какие ошибки допущены в данной способности? Jass.
» WarCraft 3 / Есть ли идеи как сделать ульту пангольера из доты?
» WarCraft 3 / Какие ошибки допущены в данной способности? Jass.
» WarCraft 3 / Как сделать стакающиеся атаки?
» WarCraft 3 / Патч игры
Ред. quq_CCCP
» WarCraft 3 / Какие ошибки допущены в данной способности? Jass.
Отдельный код должен двигать молнию, отдельный искать цели и добавлять между ними разряды молний.
Стандартная молния ищет ближайшего видимого противника, к слову были же системы движения молний на сайте? Не?
Ниже кусок кода продвинутой дотки 6.83, цепная молния 1 в 1 как дефолт:
» WarCraft 3 / Снижение брони за атаку
» WarCraft 3 / Не работает триггер
Ред. quq_CCCP
» WarCraft 3 / Формула получения exp
» WarCraft 3 / Как сделать выбор героев через таверну как в доте
» WarCraft 3 / Включить ИИ для игрока-человека
Для помощи, пишем свои скрипты.
» WarCraft 3 / Движущийся закопавшийся и нырнувший
» WarCraft 3 / Запрет выбора юнита
» WarCraft 3 / Запрет выбора юнита
» WarCraft 3 / Как использовать тип ability? Jass. MemoryHack.
» WarCraft 3 / Как использовать тип ability? Jass. MemoryHack.
Ред. quq_CCCP
» WarCraft 3 / Как использовать тип ability? Jass. MemoryHack.
Обязательно проверять на наличиее абилки и чему равен указатель, если он меньше 1 то абилки у юнита нету.
Внимательно смотри на список функций, там наделаны на все случаи жизни, выбирай не первую попавшуюся.
» WarCraft 3 / нужен эффект ауры аганима для карты iccup dota
Потом в какую из их доток, у них их 2.
» WarCraft 3 / Отображение на мини-карте союзных камер.
» WarCraft 3 / Фаталит функция из мемхака. Jass
» WarCraft 3 / Игровые платформы для 1.26а
» WarCraft 3 / Повелитель Могил