Msey
????
offline
Опыт:
67,346Активность: |
[SiMiS]Simple Missile System
((центр
Simple Missile System (система 3D снарядов)
))
Автор: Msey
Cинтаксис: vJass (для удобства сделал без cJass) Думаю, особое разъяснение не нужно, что это за система.. Снаряд:
Чейнджлог:
1.0: Релиз системы. 2.0: Полностью переписан движок системы под структуры, теперь система требует 2 библиотеки: TimerUtils и Вoundaries, избавился от хеш-таблицы, убрал лишние функции ((кат v2.0
((код vjass
library A initializer Missile requires TimerUtils optional Boundaries
globals
private group g = CreateGroup() группа для нанесения урона private constant integer MISSILE = 'h006' id дамми снаряда private constant string land = "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl" эффект при падении на землю private constant string water = "Abilities\\Weapons\\GryphonRiderMissile\\GryphonRiderMissileTarget.mdl" эффект при падении на воду private constant string explode = "Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl" эффект взрыва снаряда private constant real spd = 0.02 период срабатывания тймера private constant real ConstH = 40 +- 20 скорость private constant real DMG = 0 +1-100000 урон в области при взрыве private constant real FACTOR = 50 +- 15 коэфф. при начальном выстреле private constant real FACToR = 0 +1-2 ограничивающий коэфф прыжка private constant real HMAX = 40 +-10 высота прыжка private constant real REDUCE = 1 +-0.5 коэфф. уменьшения скорости private constant real JUMP = 20 +- 3-7 крен прыжка + доп изменения endglobals
struct Data
unit Ball
effect e real Height real HeightDiff real MoveSpeed real MoveAngle real x real y location MovePoint location cpdx location cpdy integer cpdxz integer cpdyz real z destructable dest rect r real tempSpeed real tempHeightDiff real Angle real i real is real j real js public method VectorSize takes location MovePoint returns rect set .x = GetLocationX(.MovePoint) set .y = GetLocationY(.MovePoint) return Rect(.x-50,.y-50,.x+50,.y+50) endmethod public method DBP takes unit Ball, location MovePoint returns real
set .i = GetLocationX(.MovePoint) set .is = GetUnitX(.Ball) set .j = GetLocationY(.MovePoint) set .js = GetUnitX(.Ball) return SquareRoot((.i-.is)*(.i-.is)+(.j-.js)*(.j-.js)) endmethod public method BounceEffect takes location MovePoint returns nothing set .x = GetLocationX(.MovePoint) set .y = GetLocationY(.MovePoint) if (IsTerrainPathable(.x, .y, PATHING_TYPE_FLOATABILITY) == true) then set .e = AddSpecialEffect(land, .x,.y ) else set .e = AddSpecialEffect(water,.x,.y ) endif call DestroyEffect(.e) set .e = null endmethod private static method MoveLoc takes location HLoc, real Dist, real Angle returns location
call MoveLocation(HLoc,GetLocationX(HLoc)+Dist*Cos(Angle*0.0175),GetLocationY(HLoc)+Dist*Sin(Angle*0.0175)) return HLoc endmethod private static method FilterUnits takes nothing returns boolean
if (IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO)) then return true endif return false endmethod private static method FilterDestr takes nothing returns boolean if (GetDestructableLife(GetFilterDestructable()) >= 0.405 ) then return true endif return false endmethod static method checkId takes nothing returns boolean return GetSpellAbilityId() == 'A00F' endmethod static method BallMove takes nothing returns nothing local timer t = GetExpiredTimer() local Data this = GetTimerData(t) set .Angle = .MoveAngle set .cpdx = Location(GetLocationX(.MovePoint)+2*.MoveSpeed*Cos(.MoveAngle*0.017496),GetLocationY(.MovePoint)+1*.MoveSpeed*Sin(.MoveAngle*0.017496)) set .cpdy = Location(GetLocationX(.MovePoint)+1*.MoveSpeed*Cos(.MoveAngle*0.017496),GetLocationY(.MovePoint)+2*.MoveSpeed*Sin(.MoveAngle*0.017496)) set .cpdxz = GetTerrainCliffLevel(GetLocationX(.cpdx), GetLocationY(.cpdx)) - GetTerrainCliffLevel(GetLocationX(.MovePoint), GetLocationY(.MovePoint)) set .cpdyz = GetTerrainCliffLevel(GetLocationX(.cpdy), GetLocationY(.cpdy)) - GetTerrainCliffLevel(GetLocationX(.MovePoint), GetLocationY(.MovePoint)) set .z = GetLocationZ(.MovePoint) if (I2R(.cpdxz)*100>.Height) then set .MoveAngle = 180 - .MoveAngle set .MoveSpeed = .MoveSpeed - 1 endif if (I2R(.cpdyz)*100>.Height) then set .MoveAngle = 0 - .MoveAngle set .MoveSpeed = .MoveSpeed - 1 endif call MoveLoc(.MovePoint,.MoveSpeed,.MoveAngle) set .z = .z - GetLocationZ(.MovePoint) set .Height = .Height + .HeightDiff + .z set .HeightDiff = .HeightDiff-0.75 if .Height<500 then set .r = (VectorSize(.MovePoint)) call GroupEnumUnitsInRangeOfLoc(g, .MovePoint, 200, Condition(function Data.FilterUnits)) set .dest = RandomDestructableInRectBJ(.r, Condition(function Data.FilterDestr)) if (.dest != null) then call RemoveUnit(.Ball) call ReleaseTimer(t) call RemoveRect(.r) endif if .Height<2.5 then if CountUnitsInGroup(g)>0 then call DestroyEffect(AddSpecialEffectLoc(explode, Location(GetLocationX(GetUnitLoc(.Ball)), GetLocationY(GetUnitLoc(.Ball)))) ) call UnitDamagePoint(.Ball, 0., 150 , GetUnitX(.Ball), GetUnitY(.Ball), DMG, true, true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_ACID, WEAPON_TYPE_AXE_MEDIUM_CHOP ) call RemoveUnit(.Ball) call ReleaseTimer(t) set t=null else if .MoveSpeed>3 then set .HeightDiff = -0.8*.HeightDiff set .Height = HMAX set .MoveSpeed = .MoveSpeed - REDUCE call BounceEffect(.MovePoint) else call DestroyEffect(AddSpecialEffectLoc(explode, Location(GetLocationX(GetUnitLoc(.Ball)), GetLocationY(GetUnitLoc(.Ball))))) call RemoveUnit(.Ball) set .Ball = null call ReleaseTimer(t) set t=null endif endif endif endif call SetUnitPositionLoc(.Ball, .MovePoint) call SetUnitFacing(.Ball, .MoveAngle) call SetUnitFlyHeight(.Ball,.Height,0) call RemoveLocation(.cpdx) call RemoveLocation(.cpdy) set .cpdx = null set .cpdy = null set .dest = null set .r = null set t=null endmethod
static method Shell takes player co,location cp, location tp, real dist returns thistype local Data this = .allocate() local timer t = NewTimer() set .Height = ConstH set .HeightDiff = JUMP set .MoveSpeed = dist/FACTOR set .MoveAngle = bj_RADTODEG * Atan2(GetLocationY(tp) - GetLocationY(cp), GetLocationX(tp) - GetLocationX(cp)) set .MovePoint = Location(GetLocationX(cp),GetLocationY(cp)) set .Ball =CreateUnitAtLoc(co,MISSILE,cp,.MoveAngle) call SetUnitPathing(.Ball,false) call UnitAddAbility(.Ball,'Amrf') call UnitRemoveAbility(.Ball,'Amrf') call SetTimerData(t,this) call TimerStart(t, spd, true, function Data.BallMove) set t=null return this endmethod endstruct private struct once unit c player co location cp location tp integer i real y1 real y2 real x1 real x2 real dist static method LoadStart takes nothing returns nothing local once this = .allocate() set .c = GetTriggerUnit() set .co = GetOwningPlayer(.c) set .cp = GetUnitLoc(.c) set .tp = GetSpellTargetLoc() set .i = GetPlayerId(.co) set .y1 = GetLocationY(.cp) set .y2 = GetLocationY(.tp) set .x1 = GetLocationX(.cp) set .x2 = GetLocationX(.tp) set .dist = SquareRoot((.x2-.x1)*(.x2-.x1)+(.y2-.y1)*(.y2-.y1)) call Data.Shell(.co,.cp,.tp,.dist) call RemoveLocation(.cp) call RemoveLocation(.tp) call this.destroy() endmethod endstruct private function Missile takes nothing returns nothing
local trigger t = CreateTrigger() local playerunitevent pui = EVENT_PLAYER_UNIT_SPELL_EFFECT call TriggerRegisterPlayerUnitEvent(t, Player(0), pui, null) call TriggerRegisterPlayerUnitEvent(t, Player(1), pui, null) call TriggerRegisterPlayerUnitEvent(t, Player(2), pui, null) call TriggerRegisterPlayerUnitEvent(t, Player(3), pui, null) call TriggerRegisterPlayerUnitEvent(t, Player(4), pui, null) call TriggerRegisterPlayerUnitEvent(t, Player(5), pui, null) call TriggerRegisterPlayerUnitEvent(t, Player(6), pui, null) call TriggerRegisterPlayerUnitEvent(t, Player(7), pui, null) call TriggerRegisterPlayerUnitEvent(t, Player(8), pui, null) call TriggerRegisterPlayerUnitEvent(t, Player(9), pui, null) call TriggerRegisterPlayerUnitEvent(t, Player(10), pui, null) call TriggerAddCondition( t, Condition( function Data.checkId ) ) call TriggerAddAction( t, function once.LoadStart ) set t = null set pui = null endfunction endlibrary library TimerUtils initializer init
globals private constant boolean USE_HASH_TABLE = false private constant boolean USE_FLEXIBLE_OFFSET = false private constant integer OFFSET = 0x100000 private integer VOFFSET = OFFSET private constant integer QUANTITY = 256 private constant integer ARRAY_SIZE = 8190 endglobals ==================================================================================================?
globals private integer array data[ARRAY_SIZE] private hashtable ht endglobals It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing static if(USE_HASH_TABLE) then new blue call SaveInteger(ht,0,GetHandleId(t), value) elseif (USE_FLEXIBLE_OFFSET) then orange static if (DEBUG_MODE) then if(GetHandleId(t)-VOFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif set data[GetHandleId(t)-VOFFSET]=value else new red static if (DEBUG_MODE) then if(GetHandleId(t)-OFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif set data[GetHandleId(t)-OFFSET]=value endif endfunction function GetTimerData takes timer t returns integer
static if(USE_HASH_TABLE) then new blue return LoadInteger(ht,0,GetHandleId(t) ) elseif (USE_FLEXIBLE_OFFSET) then orange static if (DEBUG_MODE) then if(GetHandleId(t)-VOFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif return data[GetHandleId(t)-VOFFSET] else new red static if (DEBUG_MODE) then if(GetHandleId(t)-OFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif return data[GetHandleId(t)-OFFSET] endif endfunction ==========================================================================================
globals private timer array tT[ARRAY_SIZE] private integer tN = 0 private constant integer HELD=0x28829022 use a totally random number here, the more improbable someone uses it, the better. endglobals ==========================================================================================
function NewTimer takes nothing returns timer if (tN==0) then If this happens then the QUANTITY rule has already been broken, try to fix the issue, else fail. debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, make sure all timers are getting recycled correctly") static if( not USE_HASH_TABLE) then debug call BJDebugMsg("In case of errors, please increase it accordingly, or set TimerUtils_USE_HASH_TABLE to true") set tT[0]=CreateTimer() static if( USE_FLEXIBLE_OFFSET) then if (GetHandleId(tT[0])-VOFFSET<0) or (GetHandleId(tT[0])-VOFFSET>=ARRAY_SIZE) then all right, couldn't fix it call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.") return null endif else if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then all right, couldn't fix it call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.") return null endif endif endif else set tN=tN-1 endif call SetTimerData(tT[tN],0) return tT[tN] endfunction ==========================================================================================
function ReleaseTimer takes timer t returns nothing if(t==null) then debug call BJDebugMsg("Warning: attempt to release a null timer") return endif if (tN==ARRAY_SIZE) then debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!") stack is full, the map already has much more troubles than the chance of bug
call DestroyTimer(t) else call PauseTimer(t) if(GetTimerData(t)==HELD) then debug call BJDebugMsg("Warning: ReleaseTimer: Double free!") return endif call SetTimerData(t,HELD) set tT[tN]=t set tN=tN+1 endif endfunction private function init takes nothing returns nothing
local integer i=0 local integer o=-1 local boolean oops = false static if( USE_HASH_TABLE ) then set ht = InitHashtable() loop exitwhen(i==QUANTITY) set tT[i]=CreateTimer() call SetTimerData(tT[i], HELD) set i=i+1 endloop set tN = QUANTITY else loop set i=0 loop exitwhen (i==QUANTITY) set tT[i] = CreateTimer() if(i==0) then set VOFFSET = GetHandleId(tT[i]) static if(USE_FLEXIBLE_OFFSET) then set o=VOFFSET else set o=OFFSET endif endif if (GetHandleId(tT[i])-o>=ARRAY_SIZE) then exitwhen true endif if (GetHandleId(tT[i])-o>=0) then set i=i+1 endif endloop set tN = i exitwhen(tN == QUANTITY) set oops = true exitwhen not USE_FLEXIBLE_OFFSET debug call BJDebugMsg("TimerUtils_init: Failed a initialization attempt, will try again") endloop if(oops) then static if ( USE_FLEXIBLE_OFFSET) then debug call BJDebugMsg("The problem has been fixed.") If this message doesn't appear then there is so much handle id fragmentation that it was impossible to preload so many timers and the thread crashed! Therefore this debug message is useful. elseif(DEBUG_MODE) then call BJDebugMsg("There were problems and the new timer limit is "+I2S(i)) call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low:") call BJDebugMsg("a) Change USE_FLEXIBLE_OFFSET to true (reduces performance a little)") call BJDebugMsg("b) or try changing OFFSET to "+I2S(VOFFSET) ) endif endif endif endfunction
endlibrary
library Boundaries initializer init
globals private constant real EXTRA = 500.0 endglobals globals private real maxx private real maxy private real minx private real miny endglobals private function dis takes nothing returns nothing local unit u=GetTriggerUnit() local real x=GetUnitX(u) local real y=GetUnitY(u) if(x>maxx) then
set x=maxx elseif(x<minx) then set x=minx endif if(y>maxy) then set y=maxy elseif(y<miny) then set y=miny endif call SetUnitX(u,x) call SetUnitY(u,y) set u=null endfunction private function init takes nothing returns nothing local trigger t=CreateTrigger() local region r=CreateRegion() local rect rc set minx=GetCameraBoundMinX() - EXTRA set miny=GetCameraBoundMinY() - EXTRA set maxx=GetCameraBoundMaxX() + EXTRA set maxy=GetCameraBoundMaxY() + EXTRA set rc=Rect(minx,miny,maxx,maxy) call RegionAddRect(r, rc) call RemoveRect(rc) call TriggerRegisterLeaveRegion(t,r, null) call TriggerAddAction(t, function dis) set t=null set r=null set rc=null endfunction endlibrary )) )) Отредактировано Msey, 15.06.2012 в 23:08. |
27.04.2012, 20:15 | #1
+7/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Cosonic5
Моймозггоритогнем
offline
Опыт:
13,584Активность: |
Молодец! А jngp надо? Отредактировано Msey, 21.05.2012 в 18:37. |
27.04.2012, 20:26 | #2
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Msey
????
offline
Опыт:
67,346Активность: |
|
27.04.2012, 20:31 | #3
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Msey
????
offline
Опыт:
67,346Активность: |
Вышла версия 2.0 |
19.05.2012, 15:05 | #4
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
quq_CCCP
Я белый и пушистый!
offline
Опыт:
94,203Активность: |
Msey, чё теперь онли структуры и таймер утилс? Ну производительность то стала ощутимо выше, или всё тока реклама? |
19.05.2012, 15:15 | #5
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Vadik29
Choice Battle 1.6а
offline
Опыт:
15,845Активность: |
Msey, понравилось + и работает быстро.... |
19.05.2012, 15:17 | #6
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Msey
????
offline
Опыт:
67,346Активность: |
да. теперь производительность стала значительно выше. У меня не лагало даже при 60+ снарядах |
19.05.2012, 15:17 | #7
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
quq_CCCP
Я белый и пушистый!
offline
Опыт:
94,203Активность: |
Msey, Ну что сказать, круто - плюсую! Конешно хотелось бы более оригинального падания в воду, но аналог такой системы я видел только в пудж варс, возможно буду юзать более урезаную версию для одной краты, появилась идея нестандартного скилла... |
19.05.2012, 15:24 | #8
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Doc
offline
Опыт:
63,163Активность: |
У меня не лагало на структурах при 400 снарядах. =) |
19.05.2012, 15:28 | #9
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
quq_CCCP
Я белый и пушистый!
offline
Опыт:
94,203Активность: |
Doc, ну от компа зависит, это раз, два такое кол во снарядов не имеет практического смысла, ну что это за мапа такая где вся карта это одни снаряды? |
19.05.2012, 15:30 | #10
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Msey
????
offline
Опыт:
67,346Активность: |
Я с большим количеством просто не проверял. Потом попробую разогнать до 150 и более) |
19.05.2012, 15:30 | #11
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
хорошая системка)
кстати есть один баг, скрин от
гранаты забились в угол и оооочень долго там прыгают. |
19.05.2012, 15:30 | #12
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Msey
????
offline
Опыт:
67,346Активность: |
Hatsume_Hate, это не баг. система Boundaries не дает им улететь за границы карты. А прыгают они долго, потому что я поставил коэффициент уменьшения прыжка на минималку, чтобы показать гибкость системы и что она не лагает при большом кол-ве снарядов. |
19.05.2012, 15:33 | #13
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
quq_CCCP
Я белый и пушистый!
offline
Опыт:
94,203Активность: |
Msey, кстати а с блокираторами путей она взаимодействует? Было бы удобно ограждать ими участки карты в которые не должен улетать снаряд... |
19.05.2012, 15:35 | #14
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
Msey:
так они там и остаются навечно. И не улетают оттуда. |
19.05.2012, 15:37 | #15
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Msey
????
offline
Опыт:
67,346Активность: |
quq_CCCP:
взаимодействует. он уничтожается при прикосновении
мб вскоре я сделаю так, чтобы от отскакивал обратно
Hatsume_Hate, тк они движутся в направлении к границам, а границы возвращают отрицательные единицы их смещения, вот поэтому они и прыгают на месте. Проверил со 150 снарядами, игра начала глючить. Видимо сам процесс подлагивает |
19.05.2012, 15:45 | #16
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
quq_CCCP
Я белый и пушистый!
offline
Опыт:
94,203Активность: |
Msey:
Видим дело в моделях снарядов, попробуй использовать снаряды попроще... И юнитов с пустыми моделями, если лагов будет меньшее время, значит алгоритм не тормозит, а если нечего не изменится, можно будет пересмотреть сам процесс... Но по мне 150 снарядов более чем достаточно... Насчёт блокираторов - мб сделать параметр не ломать а отскакивать от блокиратора? |
19.05.2012, 15:49 | #17
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Doc
offline
Опыт:
63,163Активность: |
quq_CCCP, 1.4 ггц одноядерный проц у меня был тогда. Модель - снаряд атаки тралла. И омг, такая задумка карты была.
Doc добавил: Глянул код. You're doing it wrong. |
19.05.2012, 15:55 | #18
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Msey
????
offline
Опыт:
67,346Активность: |
|
19.05.2012, 15:56 | #19
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Doc
offline
Опыт:
63,163Активность: |
Самое крупное, что заметил при беглом осмотре.
|
19.05.2012, 16:04 | #20
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|