Система отталкивает юнитов, при этом учитываеться растояние от юнита до центра отталкивания, скорость их отталкивания, а также при встрече с припятствиями юниты отлетают от них,но уже с меньшей скоростью.
Обновления: v1.1 Нормальный рекошет (сделал SirNikolas) Теперь юниты ещё реагируют на высоту рельефа. Если юнит отталкиваеться на гору то он начинает быстро тормозить, а если с горы то набирает скорость.
Импорт: Для использования в своей карте скопируйте триггер OTR.
Функции: OTR_Start(unit u,real radius,real maxdist)- отталкивает юнитов в определённом радиусе от юнита, параметр maxdist рекомендую ставить 2000, он что то вроде импульса. OTR_StartXY(player p,real x,real y,real radius,real maxdist)- отталкивает всех от точки, за исключением юнитов указанного игрока. OTR_GrUnit(unit u,real x,real y,real maxdist)- отталкивает определённого юнита. OTR_XYpr(real x,real y)- проверяет точку на проходимость.
Ты же их делал, напиши описание, а я попрошу модеров, чтобы добавили в 1 пост
Ну ладно. Функция OTR_ConvertReal используется здесь, чтобы привести угол в диапазон [0.; 360.], вернее, [0.; 2π].
Quote (SirNikolas)
Функция OTR_Ricochet определяет угол (в радианах!), по которому будет продолжать движение объект, попадающий в точку (x; y) и движущийся под углом angle. Также она берет дополнительные параметры. dist определяет, в каком радиусе нужно искать препятствие. При слишком высоких значениях функция может не заметить небольшой объект, а при низких юнит будет рикошетировать от малых шероховатостей, и следовательно, совсем в другую сторону. Оптимальное значение - 15. Чем меньше параметр step, тем выше точность рикошета, но и лаги тоже увеличиваются. Оптимальное значение - .34907. Измеряется в радианах! Параметр max показывает, под каким максимальным углом следует искать препятствие. Если оно не будет найдено под этим углом, рикошет будет в сторону, противоположную движению. Оптимальное значение - 3. Измеряется в радианах!
Использованны vJass и cJass, так что НУЖЕНJNGP с установленным AdicHelper!' Система отталкивает юнитов, при этом учитываеться растояние от юнита до центра отталкивания, скорость их отталкивания, а также при встрече с припятствиями юниты отлетают от них,но уже с меньшей скоростью. Обновления v1.1
Отличный рекошет (сделал 'SirNikolas')
Теперь юниты ещё реагируют на высоту рельефа. Если юнит отталкиваеться на гору то он начинает быстро тормозить, а если с горы то набирает скорость. v1.2
Стали доступны функции OTR_ConvertReal и OTR_Recochet
Система немного оптимизирована.
Значительно увеличина точность рекошета.
Дана возможность отключения спецэфекта, так как из-за него при отталкивание большого количества юнитов (более 30) начинаются небольшие лаги.(true - включить, false - выключить).
Дана возможность настроек параметров step и max. Если их не указывать будут использованны параметры по умолчанию.
Импорт: Для использлвания в своей карте скопируйте триггер OTR. Функции: OTR_Start(unit u,real radius,real maxdist,boolean effecton,real step,real max) - отталкивает юнитов в определённом радиусе от юнита. Параметр maxdist рекомендую ставить 2000, он что то вроде импульса. radius - радиус от x;y координат юнита, выбранные все живые, вражесские юниты в нём будут отталкиваться. Вы можете не указывать параметры step и max тоесть можно также писать call OTR_Start(u,radius,maxdist,e) или только step call OTR_Start(u,radius,maxdist,e,step), при этом они будут установленны по умолчанию. step по умолчанию - .34907 ,а max - 3.1415926536. Анологично можно делать и в функциях OTR_StartXY и в OTR_GrUnit. OTR_StartXY(player p,real x,real y,real radius,real maxdist,boolean effecton,real step,real max)- отталкивает всех от точки, за исключением юнитов указанного игрока. OTR_GrUnit(unit u,real x,real y,real maxdist,real step,real max)- отталкивает определённого юнита. OTR_XYpr(real x,real y)- проверяет точку на проходимость. (Автор следущих двух функций [/b]SirNikolas) OTR_ConvertReal(real r,real min,real max)- возвращает число в указанном диапозоне. OTR_Ricochet(real x,real y,real angle,real dist,real step,real max) - определяет угол (в радианах!) по которому будет продолжать движение объект попадающий в точку ( x;y) и движущийся под углом angle. Также она берёт доп. параметры. dist('Оптимальное значение - 15') - определяет, в каком радиусе нужно искать препятствие. При слишком высоких значениях функция может не заметить не большой объект, а при низких юнит будет рекошировать от малых шерховатостей, и следовательно, совсем в другую сторону. step('Оптимальное значение - .34907') - чем меньше это параметр , тем выше точность рикошета, но и лаги тоже увеличиваються max('Оптимальное значение - 3'(в радианах!)) - Показывает под каким максимальным углом следует искать препятствие. Если оно не будет найдено под этим углом, рикошет будет в сторону, противоположенную движение.
Code
library OTR {
define { //Значения по умолчанию===== private STEP=.34907 private MAX=3.1415926536 //========================== } //Дальше ни чего не трогать. =) private hashtable hash=InitHashtable() private location LocZ=Location(0,0) private player playercast
private struct str { unit u real speed real angle real Z real maxspeed real step real max string efmd boolean flag boolean effecton }
public boolean XYpr(real x,real y) { local item t=CreateItem('texp',x,y) local real x1,y1 SetItemPosition(t,x,y) x1=GetWidgetX(t);y1=GetWidgetY(t);RemoveItem(t);t=null return x==x1 && y==y1 }
public real ConvertReal(real r, real min, real max) { whilenot r<=max { r-=max } whilenot r>=min { r+=max } return r }
public real Ricochet(real x, real y, real angle, real dist, real step, real max) { real r=step,a=angle,x1,x2,y1,y2 do { x1=x+Cos(a)*dist ; y1=y+Sin(a)*dist exitwhen r>=max or OTR_XYpr(x1,y1) r=r+step a=ConvertReal(angle+r,.0,6.283185306) } if a==angle { return angle } r=step do { x2=x+Cos(a)*dist ; y2=y+Sin(a)*dist exitwhen r>= max or OTR_XYpr(x2, y2) a=ConvertReal(angle-r,.0,6.283185306) ; r=r+step } r=ConvertReal(3.1415926536+(Atan2(y1-y,x1-x)+Atan2(y2-y,x2-x))/2,.0,6.283185306) if r>=1.5707963265 and a>=3.1415926536 { return 2*(r+1.5707963265)-a } return 2*(r-1.5707963265)-a }
private nothing GrAc3() { timer t=GetExpiredTimer() str h=LoadInteger(hash,GetHandleId(t),0) real x=GetWidgetX(h.u),y=GetWidgetY(h.u) real x1=x+h.speed*Cos(h.angle),y1=y+h.speed*Sin(h.angle) real angle,Z=h.Z MoveLocation(LocZ,x,y) h.Z=GetLocationZ(LocZ) if h.speed>.0 && GetWidgetLife(h.u) > .0 { angle=Ricochet(x1,y1,h.angle,15.,h.step,h.max) if angle==h.angle { SetUnitX(h.u,x1) SetUnitY(h.u,y1) else h.angle = angle h.speed=h.speed-3. } if h.flag==false { h.flag=true elseif h.Z>Z h.speed=h.speed-(h.Z-Z)/10 else h.speed=h.speed+(Z-h.Z)/10 } if h.speed>h.maxspeed { h.speed=h.maxspeed } if h.effecton { DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl",x1,y1)) } h .speed=h.speed-.3 else FlushChildHashtable(hash,GetHandleId(t)) DestroyTimer(t) h.destro y() } t=null } public nothing GrUnit(unit u,real x,real y,real maxdist,boolean e,real step,real max) { timer t=CreateTimer() real xu=GetUnitX(u),yu=GetUnitY(u) str h=str.create() h.angle=Atan2(yu-y,xu-x) h.speed=maxdist/100-SquareRoot((x-xu)*(x-xu)+(y-yu)*(y-yu))/100 h.maxspeed=h.speed ;h.u=u ;h.effecton=e;h.flag=false;h.step=step;h.max=max SaveInteger(hash,GetHandleId(t),0,h) TimerStart(t,0.02,true,function GrAc3) t=null } public nothing Start(unit u,real radius,real maxdist,boolean effecton,real step,real max) { group g=CreateGroup() unit ugr real x=GetWidgetX(u),y=GetWidgetY(u) boolexpr b=Condition(function Cond) playercast=GetOwningPlayer(u) GroupEnumUnitsInRange(g,x,y,radius,b) do { ugr=FirstOfGroup(g) exitwhen ugr==null GrUnit(ugr,x,y,maxdist,effecton,step,max) GroupRemoveUnit(g,ugr) } DestroyBoolExpr (b);DestroyGroup(g) b=null;g=null } public nothing StartXY(player p,real x,real y,real radius,real maxdist,boolean effecton,real step,real max) { group g=CreateGroup();unit ugr boolexpr b=Condition(function Cond) playercast=p GroupEnumUnitsInRange(g,x,y,radius,b) do { ugr=FirstOfGroup(g) exitwhen ugr==null GrUnit(ugr,x,y,maxdist,effecton,step,max) GroupRemoveUnit(g,ugr) } DestroyBoolExpr (b);DestroyGroup(g) b=null;g=null } define { OTR_Start(u,radius,maxdist,effecton)=OTR_##Start(u,radius,maxdist,effecton,STEP,MAX) OTR_Start(u,radius,maxdist,effecton,ste p)=OTR_##Start(u,radius,maxdist,effecton,step,MAX) OTR_Start(u,radius,maxdist,effecton,step,max)=OTR_##Start(u,radius,maxdist,effecton ,step,max) OTR_StartXY(p,x,y,radius,maxdist,e)=OTR_##StartXY(p,x,y,radius,maxdist,e,STEP,MAX) OTR_StartXY(p,x,y,radius,maxdist,e ,step)=OTR_##StartXY(p,x,y,radius,maxdist,e,step,MAX) OTR_StartXY(p,x,y,radius,maxdist,e,step,max)=OTR_##StartXY(p,x,y,radius,maxdist, e,step,max) OTR_GrUnit(u,x,y,maxdist,e)=OTR_Gr##Unit(u,x,y,maxdist,e,STEP,MAX) OTR_GrUnit(u,x,y,maxdist,e,step)=OTR_Gr##Unit(u,x ,y,maxdist,e,step,MAX) OTR_GrUnit(u,x,y,maxdist,e,step,max)=OTR_Gr##Unit(u,x,y,maxdist,e,step,max) OTR_Ricochet(x,y,angle,dist)= OTR_##Ricochet(x,y,angle,dist,STEP,MAX) OTR_Ricochet(x,y,angle,dist,step)=OTR_##Ricochet(x,y,angle,dist,step,MAX) OTR_Ricochet(x ,y,angle,dist,step,max)=OTR_##Ricochet(x,y,angle,dist,step,max) } }
Сообщение отредактировал rixt7956 - Вторник, 01 Марта 2011, 10:59:07
В общем, значительных изменений не обнаружил, за исключением вызова с аргументами по умолчанию. По-моему, нет смысла писать библиотеки для общего пользования на cJASS, т. к. на нашем сайте его знают не все.
за исключением вызова с аргументами по умолчанию. По-моему, нет смысла писать библиотеки для общего пользования на cJASS, т. к. на нашем сайте его знают не все.
Так я же расписал как и что использовать. Тем более JNGP есть у всех, а изменять в самой библиотеки, не чего не надо, а функции вызываются то как и обычно