27

» WarCraft 3 / ubersplat

Немного не понял где можно в редакторе объектов прописать это. Не видел такого. нельзя кажись. Можно в гуи в редакторе триггеров посмотреть что за текстура (если они есть), но сейчас мы говорим про удар грома, знаю, что она есть в уберсплате
инструкция
  1. нажимаете "создать уберсплат"
  1. выбираете, смотрите что за текстура (там написано)
  1. можно конвентировать триггеры в код и посмотреть что за текстура (нам нужно взять строку)
Получается "THND"
  1. открываете MPQ master открываешь, в архиве находишь папку splats и оттуда извлекаешь таблицу
  1. в таблице ищешь строчку с названием "THND", записано в ней путь текстуры. Это чтоб не искать текстуры.
Но как писал выше, ищи текстуру по пути replaceable textures/splats
вот там в гуи все ли указаны? неизвестно. Смотрел, что-то в таблице мало текстур (44 шт.). Остальные, что хранятся папке по пути replaceable textures/splats, это рассовые (типа A_OrcUberSplat.blp и B_OrcUberSplat.blp и так далее - не понял что значат, и даже не разбирался, больно надо
можешь попробовать свой сплат сделать. Берешь таблицу, прописываешь новый код, новый путь текстурке и др.
Загруженные файлы
27

» WarCraft 3 / ubersplat

кому интересно, есть такая наработка у нас на форуме ссылка
27

» WarCraft 3 / ubersplat

Принятый ответ
Ну это можно для заклинаний и прочее применить. Да можно и без эффекта. Это типа поверхностные картинки всяких кратеров, поверхностей и прочее. Их можно удалить.
для тех кто не знает, чтобы появились нужно прописать (в разделе триггеры - текстура земли). для замены: лежат по пути replaceable textures/splats
аналогично и с изображением Image (в разделе триггеры - изображение)
долго пробовал создавать, у меня что-то не отображалась ни фига без render always state и rendering state. Вообще-то большинство сплатов, и image могут без rendering state отобразиться. А еще вот с изображением image какие-то траблы. если импортировать в изображение какую-нибудь иконку, то бывает текстура изображения почему то размыта или черные квадраты. Создать легко, но часто не прорисовываются изображения норм, и приходится мучаться с переделками иконок. Поможет статья см. ниже
список нативок
создать uberspat с настройками (boolean forcePaused, boolean noBirthTime). Что значат эти настройки не знаю.
native CreateUbersplat takes real x, real y, string name, integer red, integer green, integer blue, integer alpha, boolean forcePaused, boolean noBirthTime returns ubersplat
разблокирование для показа самого изображения (типа прорисовывается изображение). Без этой команды бывает не отображает уберсплат. Если поставить false, то изображение пропадает. Зачем тогда нужна команда ShowUbersplat?
native SetUbersplatRenderAlways takes ubersplat whichSplat, boolean flag returns nothing
разблокирование во избежание глюков (не знаю что это значит). Как-то связана с отображением, без этой команды в некоторых случаях, видимо, не работает уберсплат.
native SetUbersplatRender takes ubersplat whichSplat, boolean flag returns nothing
показать/спрятать
native ShowUbersplat takes ubersplat whichSplat, boolean flag returns nothing
уничтожить/удалить
native DestroyUbersplat takes ubersplat whichSplat returns nothing
завершить показ. Короче изображение пропадает. Но чаще всего не сразу. Быстрее было бы спрятать или удалить.
native FinishUbersplat takes ubersplat whichSplat returns nothing
перезапустить (короче снова отобразить). Связано с FinishUbersplat
native ResetUbersplat takes ubersplat whichSplat returns nothing
Загруженные файлы
27

» WarCraft 3 / Изменение Последователиносте работы цыкла

Принятый ответ
вот код
local group = CreateGroup()
local unit e
//выбираете всех юнитов группу g, есть в  комменте (http://xgm.guru/p/wc3/187447?postid=345848#comment10) описание всех выборок, начинающих на GroupEnum..
call GroupEnumUnitsInRange(g, x, y, 400., null)
//цикл
loop
	set e = FirstOfGroup(g)
	exitwhen e == null
	//какое-то действие, что-то делаешь с юнитом e 
	call GroupRemoveUnit(g,e)
endloop
call DestroyGroup(g)
что-то похожее есть вот здесь или тут или тут кому надо найдет на сайте
27

» WarCraft 3 / Не работает IsUnitIllusion

Следует предположение, что как только дамми получает приказ применить способность на основе Предмет:Иллюзии, условие IsUnitIllusion просто не успевает какаим-то образом сделать проверку =/
Почему каким-то?
Proshel_Doty, ну возможно они еще не созданы при касте, поэтому лови через определенное время таймером (0.00 сек или 0.01 и так далее). Лучше проверять событием - юнит вызывает боевую единицу, засовывать в группу и так далее
27

» WarCraft 3 / Юнит при приземлении после "превращения" поворачивается в 270

Принятый ответ
да, есть такое (не 270, а 240). например, у друидов-медведей не меняет угол, а у друидов-воронов меняет. ворон поворачивается до превращения. Как-то только опуститься вниз, то перевоплощается в другую форму. Думал, связано это с абилкой, пробовал другие, одно и тоже. можно периодически таймером заставлять не изменять угол поворота, и он останется таким-же
с чем связано неизвестно и бесполезно думать об этом
вот скинул наработку. это примерно, на скорую руку. вейты и прочее. нужно точное время отсчитать от каста до окончательного поворота (я от балды поставил вейт 1 сек.), на гуи
Загруженные файлы
27

» WarCraft 3 / Количество операций в одном потоке

ScopteRectuS, тоже такое делал. Помню, надо было найти площадку для стройки, задавал вопрос, и там перебирал каждую точку loop'ами. Но выяснил, что такую работу до конца не выполняет, обрыв. Приходилось там где есть лупы, отделять, и в другую функцию вставлять эти циклы. чтобы потом отдельный поток создавать через ExcecuteFunc.Только так он работал у меня
27

» WarCraft 3 / Полет снаряда по дуге

вот примеры. Ничего нового в них нет. Один пример - код из доты про рексара с топорами, и второй по параболе (там подумал еще и поднимать, и двигать в бок), единственное, что не написал возвращение. Просто лень было.
Darknessay, радиус очень сложно вычислить. Это тебе не окружность или сфера, где идеально круглое. там что вроде овала, эллипса. мб есть какие-то способы, но чтобы сделать = надо знать математику хорошо (там геометрия, тригонометрия, матрица и др)
раскрыть
радиус можно выяснить по теореме пифагора. Помнишь прямоугольный треугольник. Там есть два катета, и гипотенуза (гипотенуза это и есть радиус). горизонтальный катет = d/2, вертикальный катет = h. И там ищи по теореме пифагора. Зная, значения двух катетов, можно еще и узнать и угол (если он нужен).
Загруженные файлы
27

» WarCraft 3 / Полет снаряда по дуге

Darknessay, мб Рексара взломать? пен доту смотри
код опен дота
// OpenDota 6.41 deprotected by NETRAT and DioD
// inspired by everyone who posted on forum threads and feedback page
// based on OpenDota 6.32b, deprotected by DimonT, NETRAT and TheBloodiest
// http://dimon.xgm.ru/opendota/
// Visit our modmaking community at http://xgm.ru/

// Objects used:
// 'A0O1' = Wild Axes (Beastmaster : Rexxar)
// 'A04R' = Marker (Nether Ward 4,Lightning Bolter,Nether Ward 3,Nether Ward 2,Vengeance Death caster,...)
// 'e01T' = Boomerang
// 'Amrf' = Crow Form (Medivh)

// DEBUG Trigger Number : 34
function WildAxesSpell takes nothing returns boolean
	return GetSpellAbilityId()=='A0O1'
endfunction

function WildAxesTreeCut takes nothing returns nothing
	call KillDestructable(GetEnumDestructable())
endfunction

function WildAxesDamage takes unit pWho,real pxx,real pyy,group pVictims returns nothing
	local group lGroup=CreateGroup()
	local unit lTMP
	local rect lMx=Rect(pxx-150,pyy-150,pxx+150,pyy+150)
	call GroupEnumUnitsInRange(lGroup,pxx,pyy,150,null)
	loop
		set lTMP=FirstOfGroup(lGroup)
		exitwhen lTMP==null
		if(IsUnitInGroup(lTMP,pVictims)==false and IsUnitEnemy(lTMP,GetOwningPlayer(pWho))and IsUnitVisible(lTMP,GetOwningPlayer(pWho)))then
			if(GetUnitAbilityLevel(lTMP,'A04R')!=1 and GetUnitState(lTMP,UNIT_STATE_LIFE)>0 and IsUnitType(lTMP,UNIT_TYPE_STRUCTURE)==false)then
				call GroupAddUnit(pVictims,lTMP)
				call UnitDamageTarget(pWho,lTMP,60+GetUnitAbilityLevel(pWho,'A0O1')*30,true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_METAL_HEAVY_SLICE)
				call AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl",lTMP,"overhead")
			endif
		endif
		call GroupRemoveUnit(lGroup,lTMP)
	endloop
	call EnumDestructablesInRect(lMx,null,function WildAxesTreeCut)
	call RemoveRect(lMx)
	call DestroyGroup(lGroup)
endfunction

function WildAxesTimer takes nothing returns nothing
	local string lTable=H2Tx(GetExpiredTimer())
	local unit lAxe=GetUnit(lTable,"Axe")
	local unit lCaster=GetUnit(lTable,"Hero")
	local real lAx=GetReal(lTable,"Ax")
	local real lAy=GetReal(lTable,"Ay")
	local real lCx=GetReal(lTable,"Cx")
	local real lCy=GetReal(lTable,"Cy")
	local real lBx=GetReal(lTable,"Bx")
	local real lBy=GetReal(lTable,"By")
	local real laa=GetReal(lTable,"a")
	local real lbb=1-laa
	local boolean lIsPassed=GetBoolean(lTable,"FirstPass")
	local group lCheckGroup=GetGroup(lTable,"AlreadyDamaged")
	call SetUnitX(lAxe,SafeX(lAx*laa*laa+lBx*2*laa*lbb+lCx*lbb*lbb))
	call SetUnitY(lAxe,SafeY(lAy*laa*laa+lBy*2*laa*lbb+lCy*lbb*lbb))
	call WildAxesDamage(lCaster,GetUnitX(lAxe),GetUnitY(lAxe),lCheckGroup)
	if(lIsPassed)then
		call SetReal(lTable,"a",laa-.02)
	else
		call SetReal(lTable,"a",laa+.02)
		call SetReal(lTable,"Ax",GetUnitX(lCaster))
		call SetReal(lTable,"Ay",GetUnitY(lCaster))
	endif
	if(laa<0 and lIsPassed)then
		call SetBoolean(lTable,"FirstPass",false)
		call SetReal(lTable,"Bx",lAx+300*Cos(Atan2(lCy-lAy,lCx-lAx)+GetReal(lTable,"AngleOffset")))
		call SetReal(lTable,"By",lAy+300*Sin(Atan2(lCy-lAy,lCx-lAx)+GetReal(lTable,"AngleOffset")))
	endif
	if(laa>1 and lIsPassed==false)then
		call PauseTimer(GetExpiredTimer())
		call DestroyGroup(lCheckGroup)
		call FastFlush(lTable)
		call RemoveUnit(lAxe)
		call DestroyTimer(GetExpiredTimer())
	endif
endfunction

function WildAxesSettings takes nothing returns nothing
	local unit lCaster=GetTriggerUnit()
	local real lCasterX=GetUnitX(lCaster)
	local real lCasterY=GetUnitY(lCaster)
	local real lTargetX=GetLocationX(GetSpellTargetLoc())
	local real lTargetY=GetLocationY(GetSpellTargetLoc())
	local unit lAxe1=CreateUnit(GetOwningPlayer(lCaster),'e01T',lCasterX,lCasterY,270.)
	local unit lAxe2=CreateUnit(GetOwningPlayer(lCaster),'e01T',lCasterX,lCasterY,270.)
	local string lTable1
	local string lTable2
	local timer lTimer1=CreateTimer()
	local timer lTimer2=CreateTimer()
	if GetSpellTargetUnit()!=null then
		set lTargetX=GetUnitX(GetSpellTargetUnit())
		set lTargetY=GetUnitY(GetSpellTargetUnit())
	endif
	call UnitAddAbility(lAxe1,'Amrf')
	call UnitRemoveAbility(lAxe1,'Amrf')
	call SetUnitFlyHeight(lAxe1,150,0)
	call UnitAddAbility(lAxe2,'Amrf')
	call UnitRemoveAbility(lAxe2,'Amrf')
	call SetUnitFlyHeight(lAxe2,150,0)
	set lTable1=H2Tx(lTimer1)
	call SetHandle(lTable1,"Hero",lCaster)
	call SetHandle(lTable1,"Axe",lAxe1)
	call SetHandle(lTable1,"AlreadyDamaged",CreateGroup())
	call SetReal(lTable1,"Ax",lCasterX)
	call SetReal(lTable1,"Ay",lCasterY)
	call SetReal(lTable1,"Cx",lTargetX)
	call SetReal(lTable1,"Cy",lTargetY)
	call SetReal(lTable1,"Bx",lCasterX+300*Cos(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)+45))
	call SetReal(lTable1,"By",lCasterY+300*Sin(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)+45))
	call SetReal(lTable1,"a",1)
	call SetReal(lTable1,"AngleOffset",-45)
	call SetBoolean(lTable1,"FirstPass",true)
	set lTable2=H2Tx(lTimer2)
	call SetHandle(lTable2,"Hero",lCaster)
	call SetHandle(lTable2,"Axe",lAxe2)
	call SetHandle(lTable2,"AlreadyDamaged",CreateGroup())
	call SetReal(lTable2,"Ax",lCasterX)
	call SetReal(lTable2,"Ay",lCasterY)
	call SetReal(lTable2,"Cx",lTargetX)
	call SetReal(lTable2,"Cy",lTargetY)
	call SetReal(lTable2,"Bx",lCasterX+300*Cos(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)-45))
	call SetReal(lTable2,"By",lCasterY+300*Sin(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)-45))
	call SetReal(lTable2,"a",1)
	call SetReal(lTable2,"AngleOffset",45)
	call SetBoolean(lTable2,"FirstPass",true)
	call TimerStart(lTimer1,.025,true,function WildAxesTimer)
	call TimerStart(lTimer2,.025,true,function WildAxesTimer)
endfunction

function WildAxesInit takes nothing returns nothing
	local trigger ltt=CreateTrigger()
	call TriggerRegisterAnyUnitEventBJ(ltt,EVENT_PLAYER_UNIT_SPELL_EFFECT)
	call TriggerAddCondition(ltt,Condition(function WildAxesSpell))
	call TriggerAddAction(ltt,function WildAxesSettings)
endfunction


function InitTrig_Wild_Axes takes nothing returns nothing
endfunction
код новой доты
function R92 takes nothing returns boolean
	return GetSpellAbilityId()==1093685041
endfunction

function LWI takes nothing returns boolean
return true
endfunction

function T5I takes destructable d returns boolean
return GetDestructableTypeId(d)==1314157667 or GetDestructableTypeId(d)==1314157687 or GetDestructableTypeId(d)==1096053874 or GetDestructableTypeId(d)==1110454322 or GetDestructableTypeId(d)==1110454323 or GetDestructableTypeId(d)==1110454325
endfunction

function QDI takes nothing returns nothing
if T5I(GetEnumDestructable())and IsDestructableAliveBJ(GetEnumDestructable())then
set JJ=JJ+1
call KillDestructable(GetEnumDestructable())
endif
endfunction

function QEI takes real x,real y,real d returns integer
local rect r=Rect(x-d,y-d,x+d,y+d)
set JJ=0
call EnumDestructablesInRect(r,Condition(function LWI),function QDI)
call RemoveRect(r)
set r=null
return JJ
endfunction



function PAI takes real x1,real y1,real x2,real y2 returns real
return SquareRoot(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
endfunction





function RGI takes real y returns real
local real RDI=GetRectMinY(bj_mapInitialPlayableArea)+50
if(y<RDI)then
return RDI
endif
set RDI=GetRectMaxY(bj_mapInitialPlayableArea)-50
if(y>RDI)then
return RDI
endif
return y
endfunction

function RCI takes real x returns real
local real RDI=GetRectMinX(bj_mapInitialPlayableArea)+50
if(x<RDI)then
return RDI
endif
set RDI=GetRectMaxX(bj_mapInitialPlayableArea)-50
if(x>RDI)then
return RDI
endif
return x
endfunction

function MCI takes group g returns nothing

local integer i=GetHandleId(g)-UY

if i<0 or i>120 then

	set OJ=true

else

	call GroupClear(g)

	set QY[i]=false

	set IJ=i

endif

endfunction

function RA2 takes unit R7I,real x,real y,group WVO returns nothing
local group GK1=MDI()
local unit V11
call QEI(x,y,150)
call GroupEnumUnitsInRange(GK1,x,y,150,Condition(function LWI))
loop
set V11=FirstOfGroup(GK1)
exitwhen V11==null
if(IsUnitInGroup(V11,WVO)==false and IsUnitEnemy(V11,GetOwningPlayer(R7I)))then
if(GetUnitAbilityLevel(V11,1093678162)!=1 and GetUnitState(V11,UNIT_STATE_LIFE)>0 and IsUnitType(V11,UNIT_TYPE_STRUCTURE)==false)then
call GroupAddUnit(WVO,V11)
call UnitDamageTarget(R7I,V11,60+GetUnitAbilityLevel(R7I,1093685041)*30,true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_METAL_HEAVY_SLICE)
call AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl",V11,"overhead")
endif
endif
call GroupRemoveUnit(GK1,V11)
endloop
call MCI(GK1)
endfunction

function RB2 takes nothing returns nothing
local integer MKI=GetHandleId(GetExpiredTimer())
local unit RC2=(LoadUnitHandle(XY,(MKI),(290))) //дайми
local unit N0I=(LoadUnitHandle(XY,(MKI),(14))) //кастер
//координаты кастера
local real Ax=(LoadReal(XY,(MKI),(284)))
local real Ay=(LoadReal(XY,(MKI),(285)))
//координаты цели
local real Cx=(LoadReal(XY,(MKI),(286)))
local real Cy=(LoadReal(XY,(MKI),(287)))

local real Bx=(LoadReal(XY,(MKI),(288)))
local real By=(LoadReal(XY,(MKI),(289)))

local real a=(LoadReal(XY,(MKI),(137)))

local real b=1-a

local boolean RD2=(LoadBoolean(XY,(MKI),(291)))

local group WVO=(LoadGroupHandle(XY,(MKI),(133)))

local real RE2=RMaxBJ(PAI(Ax,Ay,Cx,Cy)/1300,0.4)

call SetUnitX(RC2,RCI(Ax*a*a+Bx*2*a*b+Cx*b*b))
call SetUnitY(RC2,RGI(Ay*a*a+By*2*a*b+Cy*b*b))

call RA2(N0I,GetUnitX(RC2),GetUnitY(RC2),WVO)

if(RD2)then

	call SaveReal(XY,(MKI),(137),((a-.02/RE2)*1.0))

else
	
call SaveReal(XY,(MKI),(137),((a+.02/RE2)*1.0))

	call SaveReal(XY,(MKI),(284),((GetUnitX(N0I))*1.0))

	call SaveReal(XY,(MKI),(285),((GetUnitY(N0I))*1.0))

endif

if(a<0 and RD2)then

	call SaveBoolean(XY,(MKI),(291),(false))

	call SaveReal(XY,(MKI),(288),((Ax+300*Cos(Atan2(Cy-Ay,Cx-Ax)+(LoadReal(XY,(MKI),(292)))))*1.0))

	call SaveReal(XY,(MKI),(289),((Ay+300*Sin(Atan2(Cy-Ay,Cx-Ax)+(LoadReal(XY,(MKI),(292)))))*1.0))

endif

if(a>1 and RD2==false)then

	call PauseTimer(GetExpiredTimer())
	
call MCI(WVO)

	call FlushChildHashtable(XY,(MKI))

	call RemoveUnit(RC2)

	call DestroyTimer(GetExpiredTimer())

endif

endfunction

function LGI takes nothing returns nothing
call DisplayTimedTextToPlayer(GetEnumPlayer(),0,U2,YJ,XJ)
endfunction

function LHI takes force LZI,real KLI,string LVI returns nothing
set XJ=LVI
set YJ=KLI
call ForForce(LZI,function LGI)
endfunction

function MDI takes nothing returns group
local integer i=IJ
loop
	exitwhen i==IJ-1
	if QY[i]==false then		
        set IJ=i+1
        if IJ==120 then
			set IJ=0
        endif
        set QY[i]=true		
        return PY[i]
    endif
	set i=i+1
	if i==120 then
		set i=0
	endif

endloop

call LHI(P2,5.00,"|c00ff0303CRITICAL ERROR: FOUND NO AVAILABLE GROUPS|r")
call LHI(P2,5.00,"|c00ff0303Send this replay to IceFrog@gmail.com|r")
return CreateGroup()

endfunction

function QTI takes unit N0I,integer QRI returns nothing
call UnitAddAbility(N0I,QRI)
call UnitMakeAbilityPermanent(N0I,true,QRI)
endfunction

function RF2 takes nothing returns nothing
local unit R7I=GetTriggerUnit()
//координаты кастера
local real Ax=GetUnitX(R7I)
local real Ay=GetUnitY(R7I)
//координаты цели
local real Cx=GetLocationX(GetSpellTargetLoc())
local real Cy=GetLocationY(GetSpellTargetLoc())
//создать dummy
local unit RG2=CreateUnit(GetOwningPlayer(R7I),1697657172,Ax,Ay,270.0)
local unit RH2=CreateUnit(GetOwningPlayer(R7I),1697657172,Ax,Ay,270.0)
//вводят для хэндлов дайми (это нужно для ключа хэша)
local integer RZ2
local integer RV2
//создаем для каждого дайми таймер
local timer RW2=CreateTimer()
local timer RX2=CreateTimer()

if GetSpellTargetUnit()!=null then
	set Cx=GetUnitX(GetSpellTargetUnit())
    set Cy=GetUnitY(GetSpellTargetUnit())
endif

//добавляет какие-то способности для дайми (видимо дает способность ворона - летать)
call QTI(RG2,1097691750) 
call UnitRemoveAbility(RG2,1097691750)
call SetUnitFlyHeight(RG2,150,0)

call QTI(RH2,1097691750)
call UnitRemoveAbility(RH2,1097691750)
call SetUnitFlyHeight(RH2,150,0)

set RZ2=GetHandleId(RW2) //хэндл таймера
call SaveUnitHandle(XY,(RZ2),(14),(R7I)) //кастер
call SaveUnitHandle(XY,(RZ2),(290),(RG2)) //дайми
call SaveGroupHandle(XY,(RZ2),(133),(MDI())) //добавляет созданную группу, функция MDI какие-то счетчики делает и прочую херню
//сохраняем координаты кастера
call SaveReal(XY,(RZ2),(284),((Ax)*1.0))
call SaveReal(XY,(RZ2),(285),((Ay)*1.0))
//сохраняем координаты цели
call SaveReal(XY,(RZ2),(286),((Cx)*1.0))
call SaveReal(XY,(RZ2),(287),((Cy)*1.0))
//сохраняем 
call SaveReal(XY,(RZ2),(288),((Ax+300*Cos(Atan2(Cy-Ay,Cx-Ax)+45))*1.0))
call SaveReal(XY,(RZ2),(289),((Ay+300*Sin(Atan2(Cy-Ay,Cx-Ax)+45))*1.0))
call SaveReal(XY,(RZ2),(137),((1)*1.0))
call SaveReal(XY,(RZ2),(292),((-45)*1.0))
call SaveBoolean(XY,(RZ2),(291),(true))

set RV2=GetHandleId(RX2)
call SaveUnitHandle(XY,(RV2),(14),(R7I))
call SaveUnitHandle(XY,(RV2),(290),(RH2))
call SaveGroupHandle(XY,(RV2),(133),(MDI()))
call SaveReal(XY,(RV2),(284),((Ax)*1.0))
call SaveReal(XY,(RV2),(285),((Ay)*1.0))
call SaveReal(XY,(RV2),(286),((Cx)*1.0))
call SaveReal(XY,(RV2),(287),((Cy)*1.0))
call SaveReal(XY,(RV2),(288),((Ax+300*Cos(Atan2(Cy-Ay,Cx-Ax)-45))*1.0))
call SaveReal(XY,(RV2),(289),((Ay+300*Sin(Atan2(Cy-Ay,Cx-Ax)-45))*1.0))
call SaveReal(XY,(RV2),(137),((1)*1.0))
call SaveReal(XY,(RV2),(292),((45)*1.0))
call SaveBoolean(XY,(RV2),(291),(true))

call TimerStart(RW2,.025,true,function RB2)
call TimerStart(RX2,.025,true,function RB2)

endfunction

function Q8I takes nothing returns boolean
	return true
endfunction

function Q9I takes trigger t,playerunitevent QAI returns nothing
local integer L9I=0
loop
	call TriggerRegisterPlayerUnitEvent(t,Player(L9I),QAI,Condition(function Q8I))
	set L9I=L9I+1
exitwhen L9I==16
endloop
endfunction

function V51 takes nothing returns nothing
local trigger t=CreateTrigger()
call Q9I(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function R92))
call TriggerAddAction(t,function RF2)
endfunction
в новой доте в коде еще кучу глобальных переменных намешаны. мне лень короч разбираться что это за переменные. завтра подробно рассмотрю этот код рексара. мне интересно как он там так двигается. проще взять код из старой опен доты и переделать, и постоянно сравнить с новым. Практически одинаков
дождись клампа
Погоди, так, момент, как может быть парабола не по Z, если при параболе юнит летит по прямой, только высота меняется, а тут он должен лететь дугой?
можно одновременно две вещи сделать (поворачивать дугой, и поднимать по оси Z), просто не знал, что тебе надо.
Загруженные файлы
27

» WarCraft 3 / Полет снаряда по дуге

примерно сделал, Ушло 5-10 часов на это математикой занимался, тригонометрию чутка подучил, пытался вставить и прочее.
угол дуги можно отсчитать если знать расстояние между кастером и целью и высоту дуги.
Парабола не только для прыжков подходит, но и для 2D движения.
Подойдет? время таймера не забудь изменить, просто для себя в качестве проверки делал.
Можно еще через эллипс сделать, но я так и не понял как там. Перечитывал статьи про эллипс, столько времени на эллипс убил.
раскрыть
Хотел сделать что-то вроде эллипса, используя нашу параболу, Проблема такая, летит плавно. Но эллипс по неведомым причинам становится огромным (юнит частенько за пределы карты вылезает), и поэтому не достигает точки. Проверка не может длину нормально проверить (если задать предел расстояния между кастером и целью 1000, то юнит где-то на половине дуги эллипса останавливается) =( возможно ошибка в моей невнимательности. Поэтому эллипс не смог заюзать
код
function Trig_Cast_Conditions takes nothing returns boolean
return( GetSpellAbilityId() == 'A000' )
endfunction

function ParabolaZ takes real h, real d, real x returns real
  return (4 * h / d) * (d - x) * (x / d)
endfunction

function Trig_Cast_Actions1 takes nothing returns nothing
//запущенный таймер и его id-хэндл
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)

local unit dummy = LoadUnitHandle(udg_Hash,id,0) //dummy

local real angle = LoadReal(udg_Hash,id,1) //угол поворота
local real h = LoadReal(udg_Hash,id,2) //высота дуги
local real d1 = LoadReal(udg_Hash,id,3) //длина дуги
local real e = LoadReal(udg_Hash,id,4) 
//координаты кастера = начальная точка дуги A
local real x1 = LoadReal(udg_Hash,id,5) 
local real y1 = LoadReal(udg_Hash,id,6)
//конечная точка дуги A2
local real x2 = LoadReal(udg_Hash,id,7)
local real y2 = LoadReal(udg_Hash,id,8)
//определение длины d2 между dummy и конечной точкой A1
local real dx = x2-GetUnitX(dummy)
local real dy = y2-GetUnitY(dummy)
local real d2 = SquareRoot(dx*dx + dy*dy)

//ввожу переменные для будущих вычислений
local real p //достаю нужную высоту с помощью функции параболы
local real A //угол параболы = не пригодился.
local real D //длина эллипса = не пригодился.
local real x
local real y



//на каждый тик таймера отодвигаем на 50 единиц (можно задать больше или меньше, например 70 или 100 на ваше усмотрение)
//e - пройденная длина от начальной A1 точки дуги, с помощью ее достаем нужную высоту p
set e = e + 50. 
set p = ParabolaZ(h,d1,e)
set A = p/e
set D = SquareRoot(e*e* ((1-Cos(A)*2)/2)+ p*p* ((1+Cos(A)*2)/2))


set x = x1 + (e * Cos(angle) - p * Sin(angle)) //e*Cos(angle+A)
set y = y1 + (e * Sin(angle) + p * Cos(angle)) //p*Sin(angle+A)
call SaveReal(udg_Hash,id,4,e) //расстояние от dummy до конечной точки дуги
if GetRectMinX(bj_mapInitialPlayableArea) < x1 and GetRectMaxX(bj_mapInitialPlayableArea) > x1 and GetRectMinY(bj_mapInitialPlayableArea) < y1 and GetRectMaxY(bj_mapInitialPlayableArea) > y1 then
    call SetUnitX(dummy,x)
    call SetUnitY(dummy,y)
else
    set d2 = 0
endif
call BJDebugMsg("дистанция между точками dummy и конечной точки дуги d: " + R2S(d2))
call BJDebugMsg("мнимая дистанция (пройденный путь от начальной точки дуги) e: " + R2S(e))
call BJDebugMsg("длина элипса D: " + R2S(D))
call BJDebugMsg("угол дуги А: " + R2S(A* bj_RADTODEG))

if d2 <= 50 then
    call PauseTimer(t)
    call DestroyTimer(t)
    call FlushChildHashtable(udg_Hash,id)
endif

set t = null
set dummy = null

endfunction

function Trig_Cast_Actions takes nothing returns nothing
//кастер
local unit u = GetTriggerUnit()
//координаты кастера
local real x1 = GetUnitX(u)
local real y1 = GetUnitY(u)
//угол поворота кастера
local real angle = GetUnitFacing(u) * bj_DEGTORAD
//длина дуги = задаем нужную длину дуги
local real d = 1000.
//высота дуги = задаем нужную высоту дуги
local real h = 300
//координаты конечной точки типа цели или точки. В данном случае, берем точку впереди на d
//Примечание: Если вы берете координаты точки каста, то нужно будет высчитать длину дуги
//У дуги две крайние точки: A1 = точка кастера, A2 = конечная точка
local real x2 = x1 + d * Cos(angle)
local real y2 = y1 + d * Sin(angle)
//рандом определяет по какой траектории дуги будет лететь вправо или влево
local integer Random = GetRandomInt(0,1)
//dummy-юнит, снаряд
local unit dummy = CreateUnit(GetTriggerPlayer(),'ewsp',x1,y1,GetUnitFacing(u))
local timer t = CreateTimer()
local integer id = GetHandleId(t)

if Random == 1 then //Если Random равен единице, то делаем высоту отрицательной. Тогда будет лететь в другую сторону
    set h = h * (-1)
endif

call SaveUnitHandle(udg_Hash,id,0,dummy)
call SaveReal(udg_Hash,id,1,angle)
call SaveReal(udg_Hash,id,2,h)
call SaveReal(udg_Hash,id,3,d)
call SaveReal(udg_Hash,id,4,0) //счетчик. сохраняем ноль. считывает нужное расстояние от начало A1 до конца A2 дуги
call SaveReal(udg_Hash,id,5,x1)
call SaveReal(udg_Hash,id,6,y1)
call SaveReal(udg_Hash,id,7,x2)
call SaveReal(udg_Hash,id,8,y2)

call TimerStart(t,0.4,true,function Trig_Cast_Actions1)

set u = null
set dummy = null
set t = null

endfunction

//===========================================================================
function InitTrig_Cast takes nothing returns nothing
    set gg_trg_Cast = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Cast, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Cast, Condition( function Trig_Cast_Conditions ) )
    call TriggerAddAction( gg_trg_Cast, function Trig_Cast_Actions )
endfunction
Кстати я как всегда немного поспешил, нужно исправить вот тут
раскрыть
if d2 <= 50 then
    call PauseTimer(t)
    call DestroyTimer(t)
    call FlushChildHashtable(udg_Hash,id)
endif
изменить строчку вместо 50 поставить 150
if d2 <= 150 then
Загруженные файлы
27

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

вот я бы заплатил бы эту "злую" тысячу
тоже купил бы. Проблема еще в том, что я уже практически не играю в варик, только ради редактора сижу маленько. Что-то делаю, для своей карты. И пока ни разу не выпустил карты....медленно делаю, 5 раз удалял карты до ... Necris делаю, наполеоновские планы насчет нее. Мне нравится идея, но сама карта надоела (сырая), требует скорейшего добавления чего нового. Если это будет в редакторе, то это упростит, этого не хватало в карте
27

» WarCraft 3 / Как на Jass быстро посчитать количество боевых единиц?

Есть ли возможность сделать то же без перебора группы?
Нативки такой не видел, нет такой. Есть близзардская Bj-функция CountUnitsInGroup, там перебираем всех и складываем. И нативку GetPlayerStructureCount, показывающую, видимо, кол-во здании
отслеживать появление и исчезновение юнитов с карты с помощью счетчика. При появлении +1, при исчезновении -1. Нужно продумать все факторы: например, юнит красного игрока (-1) перешел на сторону синего игрока (+1) (короче смена хозяина). При событии юнит входит в зону может отслеживать москитов, призывников, что может не всегда нужно. Труднее отследить исчезновение, ведь неизвестно, что вам нужно? только живые? смерть отслеживанием событием юнит умирает (-1). Но этот труп можно воскресить (+1). Если нужно отследить исчезновение трупа юзаем (событие - юнит вышел из региона).
Знаю может быть муторным делом, но если проработать, то не нужно циклом будет делать. Сразу из переменной доставать значение будешь. Либо с группой (Bj-функция CountUnitsInGroup или loop с FirstOfGroup, по-другому никак.
Но у тебя BJ-функция GetUnitsInRectOfPlayer утекает =(( и группой в конце не удаляем
27

» WarCraft 3 / Как создать конусные заклинания?

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

» WarCraft 3 / Функция проверки количества предметов по области

Принятый ответ
что тут не понятного. ну ты берешь все итемы в области с помощью Pick every item in ... и начинаешь перебирать. Это обычный же цикл. Как это работает? Эта команда Pick every item in ... - цикл, берет все предметы, затем берет один предмет в переменную Picked Item, что-то с ним делаем, Потом берет второй в переменную Picked Item, и также что-то делаем с этим предметом, и так далее. Но можно внутри этого цикла счетчик намутить. целочисленная переменная count - счетчик. Если у тебя 5 предметов, то можешь 5 действий совершить, короче будет 5 раз прибавлять число в count +1.
Честно, как-то лень объяснять. Если надо, проверить тип. То можно фильтр вставить с проверкой (типа matching item == цветок) или внутри вставить конструкцию if then endif с проверкой типа (Picked item == цветок). В фильтрах используют переменные matching item а в циклах Picked item
скрины с картами
ссылка на карту 1
ссылка на карту 2

С рунами, кстати, есть проблема. Это всякие монетки, книжки, зведолисты и прочее. Когда ты подбираешь, они исчезают, короче ничего в инвентарь себе не положишь. Но на карте эти руны остаются, и поэтому счетчик будет прибавлять и их. Из-за чего будет неправильное количество отображать. Есть даже статья
Чтобы такого не было, при подборе удаляйте руны (они ведь исчезают)
Загруженные файлы
27

» WarCraft 3 / Как создать конусные заклинания?

много букв
Так для "не смотрит" нужно чтобы юнит попал в большой промежуток?
да, тебе выше скрин даже нарисовал. в твоем случае, как определить видит ли цель кастера, то очень подойдет. для твоего скила "удар в спину". Есть другие примеры, может они то тебе подойдут. Загляни на хабр по ссылке, там точь твой вариант, описывают пример про стражника (если не понятно, смотри у меня скалярные векторы в комменте 6, 7). Конечно, тебе немного переделать надо будет, вместо кастера цель.
Если способность, скажем, через всю карту используется, а тут указывается радиус - если кастер будет за радиусом, что тогда?
если ты про молнии, то тут у меня никакого ограничительного радиуса нет. Есть радиус круга = 800, но это чисто для молнии, не стал молнии растягивать на всю карту.
В первом случае, работы со многими юнитами включает с группой, там есть ограничение радиуса - сам радиус. Когда ты пикаешь вокруг юнитов в группу, есть функции, которые выбирают всех вокруг точки с радиусом. Вот это я и использовал. Если надо убрать ограничение, используй другие функции пика на всю карту, или ставь радиус 99999
В случае, с треугольником. Можно, вместо треугольника вставлять прямоугольник =)
Во втором случае, там с одним юнитом (не работаю с группой). Коммент 7 скинул пример. Там нет ограничения, и можно на всю карту. Есть надо ограничить, тогда надо еще проверять расстояние между двумя юнитами. Если расстояние между двумя юнитами меньше 800, то делать ...
Загруженные файлы
27

» WarCraft 3 / Как создать конусные заклинания?

Обзор_в_180_градусов сделано для новичков
На основе взяты выше перечисленные примеры. Можете проверить стоит ли впереди или нет.
Кстати, формула Warden работает не так как хотелось бы. Тестировал. И выяснил, что работает если обзор не слишком большой ( angle < 180, если хотите 180 тогда придется ставить приблизительно 179). Если слишком большой, то не будет работать.
Короче тут формула берет минимальный промежуток между углами, а не большой. Пример на скрине
А так все в норме
Еще не забудьте поставить вместо udg_Target переменную GetSpellTargetUnit()
27

» WarCraft 3 / Какая то хрень с ифами :(

Принятый ответ
наброски
скидывал тебе это, что не помогло?
и проверяй дебагом, работает = не работает.
27

» WarCraft 3 / Какой должна быть сборка wc3, чтобы делать карту в 2к18?

quq_CCCP, тогда библиотеку всех функции вшить в jngp, включая RenderEdge. Сам хотел попробовать мемхак, так лень разбираться, что надо делать "чтобы это заработало", и не знание чего не дало запустить (обычный мемхак ладно, а RenderEdge...)
27

» WarCraft 3 / Как определить, находится ли в процессе постройки/улучшения здан

как сказал pro100master,
Событие юнит начинает строительство
здание, установлено. Но нужно до конца достроить = (сохраняем true)

Событие юнит прекращает строительство
прервано строительство через кнопку отмена = (сохраняем false)

Событие юнит завершает строительство
здание построенно (сохраняем false)

Событие юнит умирает = с проверкой что это здание и строилось ли оно = (сохраняем ffalse)

true/false - установка в логическую переменную. True говорит о том, что здание строится, а false нет.
можно использовать хэндл + хэш или массивы + цикл для хранения
проще простого, с улучшением здания тоже самое посмотри в гуи - там события про апгрейды (начинает улучшение/прерывает улучшение/ завершает улучшение)
27

» WarCraft 3 / Заставить ИИ юзать Морф

Принятый ответ
Этого никто не знает. У меня вот ИИ-боты сами новые предметы не могут купить, пока не положишь. Некоторые даже не принимает и продает/выбрасывает (оказывается есть типы итемов, и итемы, которые сделаны на этой основе, ИИ заставляет продавать. Брал другой подходящий тип, который бот не продаст, и им же заменял, или на его основе создавал новый).
не пробовали на триггерах ИИ написать. Это правда может быть сложнее. Щас пробую со системой строительства намутить, пробую полную ветку здании строить. Сами строят. Можно даже отойти чай пить, пока ваши юниты строят. Со строительством может и прокатит, а вот с войсками? Там трудного ничего нет. Нанял, накопил войско. Мне пока не хватает знании, так как классический вар мало играю. Не знаю каких юнитов нужно нанимать и в каких количества, там порядок. В битве какие заклинания применять и прочее? Это оказалось сложнее, много всего