function MoveU takes unit u, real dist, real angle returns nothing call SetUnitPosition(u,GetWidgetX(u)+dist*Cos(angle*bj_DEGTORAD),GetWidgetY(u)+dist*Sin(angle*bj_DEGTORAD)) call SetUnitFacing(u,angle) set u=null endfunction
function MoveUex takes unit u, real dist, real angle returns nothing call SetUnitX(u,GetWidgetX(u)+dist*Cos(angle*bj_DEGTORAD)) call SetUnitY(u,GetWidgetY(u)+dist*Sin(angle*bj_DEGTORAD)) set u=null endfunction
MoveUex сдвигает юнита u на dist ед. расстояния в сторону angle не прерывая действий юнита MoveU сдвигает юнита u на dist ед. расстояния в сторону angle, прерывая текущие действия и поворачивая юнита в сторону angle
Code
function StunLoop takes nothing returns nothing local timer t = GetExpiredTimer() local integer th = GetHandleId(t) local unit u = LoadUnitHandle(udg_Data, th, 1) local integer ui=GetHandleId(u)
function StunUnit takes unit u, unit v, real time, real bonusdmg returns nothing local timer t = CreateTimer() local integer vi=GetHandleId(v) if u!=null and bonusdmg != null and bonusdmg > 0 then call UnitDamageTarget(u,v,bonusdmg, true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS) endif
if LoadReal(udg_Data,vi), 15) > 0 then if LoadReal(udg_Data, vi, 15)<time then call SaveReal(udg_Data, vi,15, time) endif else call PauseUnit(v, true) call SaveUnitHandle(udg_Data, GetHandleId(t), 1, v) call SaveReal(udg_Data, vi,15, time) call SaveEffectHandle(udg_Data,vi, 16, AddSpecialEffectTarget("Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl", v, "overhead")) call TimerStart(t, 0.02, true, function StunLoop) endif
set t = null set u=null set v=null endfunction
Функция заставляет юнита u оглушить юнита v на time секунд и нанести дополнительно bonusdmg ед. урона. Если юнит, находясь в оглушении получит оглушение более короткое чем оставшееся на юните - функция не запишет новое значение в переменную time, так же при передаче аргументов в функцию можно заменить первый аргумент на null а последний на 0 для того что бы просто оглушить юнита.
Code
function UnitGetItemById takes unit whichUnit, integer itemId returns item local integer l=1 local item it=null
loop exitwhen l>6 if GetItemTypeId(UnitItemInSlot(whichUnit,l))==itemId then set it=UnitItemInSlot(whichUnit,l) endif set l=l+1 endloop
return it
endfunction
Функция возвращает item по типу itemid находящийся на руках у unit u
Code
function GATcb takes nothing returns nothing local timer t=GetExpiredTimer() local integer ti=GetHandleId(t) local unit u=LoadUnitHandle(udg_Data,ti,0) local integer ui=GetHandleId(u) local integer abilcode=LoadInteger(udg_Data,ti,1) local real time=LoadReal(udg_Data,ui,abilcode)
if time>0 then set time=time-0.1 call SaveReal(udg_Data,ui,abilcode,time) else call UnitRemoveAbility(u,abilcode) call SaveReal(udg_Data,ui,abilcode,0) call FlushChildHashtable(udg_Data,GetHandleId(t)) call DestroyTimer(t) set t=null endif
endfunction
function GiveAbilityTimed takes unit u, integer abilcode, integer lvl, real duration returns nothing local timer t local integer ui =GetHandleId(u) local integer ti if LoadReal(udg_Data,ui,abilcode) == null or LoadReal(udg_Data,ui,abilcode)<=0 then set t=CreateTimer() set ti=GetHandleId(t) call UnitAddAbility(u,abilcode) call SetUnitAbilityLevel(u,abilcode,lvl) call SaveInteger(udg_Data,ti,1,abilcode) call SaveUnitHandle(udg_Data,ti,0,u) call SaveReal(udg_Data,GetHandleId(u),abilcode,duration) call TimerStart(t,0.1,true,function GATcb) set t=null else call SaveReal(udg_Data,ui,abilcode,duration) if GetUnitAbilityLevel(u,abilcode) != lvl then call SetUnitAbilityLevel(u,abilcode,lvl) endif endif endfunction
Функция добавляет юниту х способность abilcode уровня lvl на duration секунд. При повторном вызове перезаписывает значения если есть разница в уровне и новая длительность больше старой длительности.
Code
function IALcb takes nothing returns nothing local timer t=GetExpiredTimer() call DecUnitAbilityLevel(LoadUnitHandle(udg_Data,GetHandleId(t),0),LoadInteger(udg_Data,GetHandleId(t),1)) call FlushChildHashtable(udg_Data,GetHandleId(t)) call DestroyTimer(t) set t=null endfunction
function IncAblLvlTimed takes unit u, integer abilcode, real duration returns nothing local timer t=CreateTimer() call UnitAddAbility(u,abilcode) call IncUnitAbilityLevel(u,abilcode) call SaveInteger(udg_Data,GetHandleId(t),1,abilcode) call SaveUnitHandle(udg_Data,GetHandleId(t),0,u) call TimerStart(t,duration,true,function IALcb) set t=null endfunction
Увеличивает уровень способности abilcode юнита u на duration секунд. Функция нужна для способностей на подобии старой пассивки тролля в доте. Осторожно - способность не проверяет максимальный уровень способности.
function DummyCast takes unit u, unit targ, integer SpellId,integer lvl, string order returns nothing local unit du = CreateUnit(GetOwningPlayer(u),'h000',GetUnitX(u),GetUnitY(u),bj_RADTODEG * Atan2(GetWidgetY(targ) - GetWidgetY(u), GetWidgetX(targ) - GetWidgetX(u))) call UnitAddAbility(u,SpellId) call SetUnitAbilityLevel(u,SpellId,lvl) call IssueTargetOrder(du,order,targ) call UnitApplyTimedLife(du,'BTLF',0.5) set du = null set u=null set targ=null endfunction
function DummyCastCords takes unit u, real x, real y, integer SpellId,integer lvl, string order returns nothing local unit du = CreateUnit(GetOwningPlayer(u),'h000',x,y,0) call UnitAddAbility(u,SpellId) call SetUnitAbilityLevel(u,SpellId,lvl) call IssuePointOrder(du,order,x,y) call UnitApplyTimedLife(du,'BTLF',0.5) set du = null set u=null endfunction[/code] Функции берут unit u (владелец), создают для него дамми и заставляют применить SpellId уровня lvl строкой order (в первом случае) на юнита targ, во втором случае на точки x,y.
Code
function GetInvItemCount takes unit whichUnit, integer itemId returns integer local integer index local integer i=0
set index = 1 loop
if GetItemTypeId(UnitItemInSlot(whichUnit, index)) == itemId then set i =i+ 1 endif
set index = index + 1 exitwhen index > bj_MAX_INVENTORY endloop return i endfunction
Функция возвращает текущее количество предметов типа itemId у юнита whichUnit, требуется для корректной работы предметных пассивных\активных способностей.
Code
function CooldownSlotLoop takes nothing returns nothing local timer t=GetExpiredTimer() local unit u=LoadUnitHandle(udg_Data,GetHandleId(t),0) local integer checkslot =LoadInteger(udg_Data,GetHandleId(t),1) local real timeleft=LoadReal(udg_Data,GetHandleId(u),checkslot)
if timeleft <= 0 then call FlushChildHashtable(udg_Data,GetHandleId(t)) call DestroyTimer(t) call SaveReal(udg_Data,GetHandleId(u),checkslot,0) else call SaveReal(udg_Data,GetHandleId(u),checkslot,timeleft-0.1) endif
set t=null set u=null endfunction
function CooldownSlot takes unit u, integer checkslot, real duration returns nothing local timer t local integer ti=GetHandleId(u) local boolean b=LoadReal(udg_Data,ti,checkslot)!=null and LoadReal(udg_Data,ti,checkslot)>0
if b==false then set t=CreateTimer() call SaveUnitHandle(udg_Data,GetHandleId(t),0,u) call SaveInteger(udg_Data,GetHandleId(t),1,checkslot) call TimerStart(t,0.1,true,function CooldownSlotLoop) set t=null endif
endfunction
function CheckCDSlot takes unit u, integer checkslot returns boolean return LoadReal(udg_Data,GetHandleId(u),checkslot) == null or LoadReal(udg_Data,GetHandleId(u),checkslot)==0 endfunction
набор функций для проверки отката пассивных навыков да и любых других навыков. В нужном месте добавьте откат call CooldownSlot(unit,spellrawcode,duration) и проверяйте откатывающийся слот if CheckCDSlot(u,spellrawcode) then
library CasterSystem initializer Init globals public constant integer DUMMY_MAX = 9 public constant integer DUMMY_TYPES_MAX = 1 public constant real DUMMY_LIFE = 1. public unit array Dummy public integer array Type public boolean array Free public timer array Timer private unit u endglobals
public function DummyTimer takes nothing returns nothing local handle h = GetExpiredTimer() local integer i = 0 loop exitwhen h == Timer[i] set i = i + 1 endloop set Free[i] = true set h = null endfunction
public function GetDummy takes player id, integer unitid, real x, real y, real face returns unit local integer i = 0 loop exitwhen unitid == Type[i] if i == DUMMY_TYPES_MAX then set u = CreateUnit(id, unitid, x, y, face) call UnitApplyTimedLife(u, 'BTLF', DUMMY_LIFE) call SetUnitExploded(u, true) return u endif set i = i + 1 endloop set i = i * (DUMMY_MAX + 1) loop exitwhen i == (DUMMY_TYPES_MAX + 1) * (DUMMY_MAX + 1) if Free[i] then set Free[i] = false call SetUnitOwner(Dummy[i], id, false) call SetUnitX(Dummy[i], x) call SetUnitY(Dummy[i], y) call SetUnitFacing(Dummy[i], face) call TimerStart(Timer[i], DUMMY_LIFE, false, function DummyTimer) return Dummy[i] endif set i = i + 1 endloop set u = CreateUnit(id, unitid, x, y, face) call UnitApplyTimedLife(u, 'BTLF', DUMMY_LIFE) call SetUnitExploded(u, true) return u endfunction
private function Init takes nothing returns nothing local integer i = 0 set Type[0] = 'h000' set Type[1] = 'h001' loop set Free[i] = true set Dummy[i] = CreateUnit(Player(15), Type[i / (DUMMY_MAX + 1)], .0, .0, .0) exitwhen i == (DUMMY_TYPES_MAX + 1) * DUMMY_MAX set i = i + 1 endloop endfunction endlibrary
Всего типов дамми - (DUMMY_TYPES_MAX + 1); дамми на каждый тип - (DUMMY_MAX + 1); время жизни дамми - DUMMY_LIFE. Все типы дамми нужно указать в функции Init. Если вдруг занятых дамми окажется больше, чем задано, создастся новый и получит "таймер жизни".
Добавлено (26-05-2011, 18:17) --------------------------------------------- Разумеется, у данной библиотеки минимальный функционал, но все остальное можно построить на ней.
SirNikolas, да просто сам писал эту систему, я сразу в нест. код карты писал, это правильно?
Добавлено (01-06-2011, 20:21) --------------------------------------------- Может кому-нибудь понадобится, это расстояние от точки 1 до точки 2 в 3D: function Dist3D takes real x1, real y1, real z1, real x2, real y2, real z2 returns real return SquareRoot((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1)) endfunction
Добавлено (01-06-2011, 20:36) --------------------------------------------- function StopUnit takes unit u returns nothing call PauseUnit(u, true) call IssueImmediateOrderById(u, 851972) call PauseUnit(u, false) endfunction По названию понятно че за функция.
Добавлено (03-06-2011, 12:27) --------------------------------------------- function DisplayTextToAllies takes integer p,real dur,string s returns nothing local integer i=0 loop if ArePlayersAlly(p,i)or i==p then call DisplayTimedTextToPlayer(Player(i),0.,0.,dur,s) endif set i=i+1 exitwhen i>11 endloop endfunction
вообще из другой оперы. Caster System = Elemental Damage, Spell Casting System, Missle System, Buff System, фрагменты я выложил (даммикаст, кулдаун слот)...; Ну и куча апи для работы с эффектами, спеллами и прочими ништяками..
function ReadCode_1 takes nothing returns nothing call Preloader(name) endfunction function ReadCode takes string name_file returns nothing set name = name_file call ExecuteFunc("ReadCode_1") endfunction
Должны быть включенны лок файлы. можно прописать так:
Code
[HKEY_CURRENT_USER\Software\Blizzard Entertainment\Warcraft III] "Allow Local Files"=dword:00000001
Главная функция в этом файле -
function PreloadFiles takes nothing returns nothing //ваш код endfunction
переменная name - путь к вашему файлу (напр "war\\tf.txt")
очень полезно при тесте карты, когда её можно не закрывать, но вносить поправки. (все глобальные переменные, функции игры нельзя использовать в этом коде, но их можно перенести. если объявляете глобальные переменные в вашем файле,область видимости переменных - данный файл.
globals unit array Caster hashtable Hash endglobals function Hashex takes nothing returns nothing // заканчивает спелл local timer t = GetExpiredTimer() local unit u =LoadUnitHandle(Hash, GetHandleId(t), 1) call BJDebugMsg(GetUnitName(u)) call PauseUnit(u, false) set Caster[1] = null call FlushChildHashtable(Hash, GetHandleId(t)) call DestroyTimer(t) set t = null set u = null
endfunction
function Pg takes nothing returns nothing // это функция запускающая движение, которое реализуется ниже local timer t = CreateTimer() local unit u = GetSpellAbilityUnit() set Hash=InitHashtable() if GetSpellAbilityId() == 'A01T' then call SaveUnitHandle(Hash, GetHandleId(t), 1, u) set Caster[1] = u call PauseUnit(u, true) call TimerStart(t, 1, false, function Hashex) set u=null endif endfunction
function My takes nothing returns nothing // это соеденино с малым переодиком local unit u = Caster[1] local real angle = GetUnitFacing(u) * bj_DEGTORAD local real distance = 8 call SetUnitX(u,GetUnitX(u)+distance*Cos(angle)) call SetUnitY(u,GetUnitY(u)+distance*Sin(angle)) call EnumDestructablesInCircleBJ(100, GetUnitLoc(u), function Killtree) set u = null endfunction
Как можно оптимизировать?
Добавлено (14-06-2011, 09:46) --------------------------------------------- Эллесар, кстати, ф-ю прелоад лучше же использовать в иниц. карты? если это та, о которой думаю я ( создание спецеффектов, и других ресурсов для спеллов и их удаление)
ФЕНИКС ЧО
Сообщение отредактировал subaku - Вторник, 14 Июнь 2011, 09:45:19
все глобальные переменные, функции игры нельзя использовать в этом коде, но их можно перенести.
Каким образом?
subaku, твой код проще переписать с нуля.
Code
globals constant hashtable Hash = InitHashtable() boolexpr Spell_Filter real MapMinX//bj_mapInitialPlayableArea задается в функции main, поэтому константами их делать нельзя real MapMaxX real MapMinY real MapMaxY real Spell_X real Spell_Y endglobals
function Trig_Spell_TreeFilter takes nothing returns boolean local destructable d = GetFilterDestructable() local real x = GetWidgetX(d) - Spell_X local real y = GetWidgetY(d) - Spell_Y if x * x + y * y <= 10000. then//100^2 call KillDestructable(d) endif set d = null return false endfunction
function Trig_Spell_Timer takes nothing returns nothing local timer t = GetExpiredTimer() local integer id = GetHandleId(t) local integer i = LoadInteger(Hash, id, 1) local unit u = LoadUnitHandle(Hash, id, 0) local rect r set Spell_X = GetWidgetX(u) + LoadReal(Hash, id, 2) set Spell_Y = GetWidgetY(u) + LoadReal(Hash, id, 3) if Spell_X > MapMinX and Spell_X < MapMaxX then call SetUnitX(u, Spell_X) endif if Spell_Y > MapMinY and Spell_Y < MapMaxY then call SetUnitY(u, Spell_Y) endif set r = Rect(Spell_X - 50., Spell_Y - 50., Spell_X + 50., Spell_Y + 50.) call EnumDestructablesInRect(r, Spell_Filter, null) call RemoveRect(r) if i == 19 then call PauseTimer(t)//Антибаг call DestroyTimer(t) call FlushChildHashtable(Hash, id) call PauseUnit(u, false) else call SaveInteger(Hash, id, 1, i + 1) endif set t = null set u = null set r = null endfunction
function Trig_Spell_Actions takes nothing returns nothing local unit u = GetTriggerUnit() local timer t = CreateTimer() local integer id = GetHandleId(t) local real a = GetUnitFacing(u) * .0174532925166 call SaveAgentHandle(Hash, id, 0, u) call SaveInteger(Hash, id, 1, 1) call SaveReal(Hash, id, 2, 8. * Cos(a)) call SaveReal(Hash, id, 3, 8. * Sin(a)) call PauseUnit(u, true) call TimerStart(t, .05, true, function Trig_Spell_Timer) set u = null set t = null endfunction
function InitTrig_Spell takes nothing returns nothing local trigger trig = CreateTrigger() local integer i = 0 set MapMinX = GetRectMinX(bj_mapInitialPlayableArea) set MapMaxX = GetRectMaxX(bj_mapInitialPlayableArea) set MapMinY = GetRectMinY(bj_mapInitialPlayableArea) set MapMaxY = GetRectMaxY(bj_mapInitialPlayableArea) set Spell_Filter = Filter(function Trig_Spell_TreeFilter) loop call TriggerRegisterPlayerUnitEvent(trig, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null) exitwhen i == 15 set i = i + 1 endloop call TriggerAddCondition(trig, Filter(function Trig_Spell_Conditions)) call TriggerAddAction(trig, function Trig_Spell_Actions) set trig = null endfunction
для строки меняют имя, 15 игрока к примеру. для реального позицию стартовой точки...
Если надо запустить свою функцию, то нужно использовать ExecuteFunc("имя функции")
Quote (subaku)
Эллесар, О_О нифинга себе...
это ещё цветочки, ягодки, когда читаешь данные с интернета. Возможно создавать игру для более 12 игроков...хранить данные игрока, переход из одной карты в другую.
Ага, я пытался разобраться в Data Manager'е. Но если нам нужно сохранить две строки, в качестве имени игрока запишется только последняя.
а экзекут для чего? сначало меняй имя игрока, потом вызываем Execute("ex_string")
function ex_string takes nothing returns nothing //записываем в любую переменную имя игрока set Mystr[kount] = Имя игрока set kount = kount + 1 endfunction
то есть в файле меняем имя игрока, и записываем стринг в переменную. И можно повторить
Сообщение отредактировал Эллесар - Вторник, 14 Июнь 2011, 20:55:55
это ещё цветочки, ягодки, когда читаешь данные с интернета. Возможно создавать игру для более 12 игроков...хранить данные игрока, переход из одной карты в другую.
На хгме же был проект ММО на варике, даже некоторое время играли, а сейчас загнулся на неопределённый срок этот серв.
Может уже было.но все же вдруг кто забыл. Ну опоптные Jassers самыи сделают но новичкам думаю пригодится ф-ия по создаюнию дами добавление абилки и кастом ее в точку
Code
function AbUnit takes unit u,integer id,integer lvl,real time,integer order,real x,real y returns nothing call UnitApplyTimedLife(u,'BTLF',time) call UnitAddAbility(u,id) call SetUnitAbilityLevel(u,id,lvl) call IssuePointOrderById(u,order,x,y) endfunction
^ кликабельно Archers Of The Island v1.8 - на стадии завершения