找回密码
 点一下
查看: 3740|回复: 1

基于在下自己写的DataSystem的Cycle/DamageUnitWithBlot函数,比较完美的解决方案。

[复制链接]
发表于 2007-12-28 19:48:43 | 显示全部楼层 |阅读模式
这个是循环提供的几个函数(附带演示地图)
伤害函数在1楼

function SYS_MassCycleInit takes integer TypeId,boolean EndRemove, unit ou,real time,real r,real d,real ad,real inv,integer MaxUnitNum returns timer
为一个单位初始化一个特征码为i的循环并自动运行,如果单位存在该特征循环则重新新设置该循环持续时间和最大单位数量

function SYS_MassCycleLoop takes nothing returns nothing
转圈的主函数,和某个Timer绑定并运行即可

function GetMassCycleTimer takes unit ou,integer i returns timer
可以用来获取单位ou特征码为i的循环用计时器

function SYS_MassCycleGetUnitNum takes unit ou,integer TypeId returns integer
可以用来获取单位ou特征码为i的循环单位数量

function SYS_MassCycleGetUnit takes unit ou,integer TypeId returns unit
从单位ou特征码为i的循环中取出一个单位

function SYS_MassCycleAddUnit takes unit ou,integer TypeId,unit u returns boolean
为单位ou特征码为i的循环增加一个单位u

[jass]//================
function SYS_MassCycleLoop takes nothing returns nothing
   local integer tmIndex = GetTimerIndex(GetExpiredTimer())
   local unit u
   local unit ou = SYS_TimerData_U00[tmIndex]
   local integer uIndex = GetUnitUserData(ou)
   local real x
   local real y
   local real ox = GetUnitX(ou)
   local real oy = GetUnitY(ou)
   local real angleTemp = 0.00
   local real angleCurrent = SYS_TimerData_R00[tmIndex]
   local real angleAdd = SYS_TimerData_R01[tmIndex]
   local real r = SYS_TimerData_R02[tmIndex]
   local real inv = SYS_TimerData_R03[tmIndex]
   local real timeLeft = SYS_TimerData_R04[tmIndex]
   local real FacingConfig = 0.00
   local integer uNum = SYS_TimerData_I01[tmIndex]
   local boolean EndRemove = SYS_TimerData_B00[tmIndex]
   local integer i = 1
   local boolean Invisable = IsUnitInvisible(ou,Player(PLAYER_NEUTRAL_PASSIVE))
   if(angleAdd>0.00)then
      set FacingConfig = 90.00
   elseif(angleAdd<0.00)then
      set FacingConfig = -90.00
   else
      return
   endif
   set angleCurrent = angleCurrent + angleAdd
   set timeLeft = timeLeft - inv
   if(angleCurrent>=360.00)then
      set angleCurrent = I2R(ModuloInteger(R2I(angleCurrent),360))
   elseif(angleCurrent<=-360.00)then
      set angleCurrent = -I2R(ModuloInteger(-R2I(angleCurrent),360))
   endif
   if(uNum==0 or GetUnitState(ou,UNIT_STATE_LIFE)<=0.00)then
      set timeLeft = 0.00
   endif
   set SYS_TimerData_R00[tmIndex] = angleCurrent
   set SYS_TimerData_R04[tmIndex] = timeLeft
   loop
      exitwhen(i>uNum)
      set u = TimerDataConfig_Unit(tmIndex,i,false,null)
      if(u!=null)then
         set angleTemp = angleCurrent + (360.00*(I2R(i-1)/I2R(uNum)))
         set x = ox + Cos(angleTemp*bj_DEGTORAD)*r
         set y = oy + Sin(angleTemp*bj_DEGTORAD)*r
         call SetUnitX(u,x)
         call SetUnitY(u,y)
         call SetUnitFacing(u,angleTemp+FacingConfig)
         if(not(Invisable) and GetUnitAbilityLevel(u,'Agho')>0 and GetUnitTypeId(u)!='ushd')then
            call UnitRemoveAbility(u,'Agho')
         elseif(Invisable and GetUnitAbilityLevel(u,'Agho')<=0)then
            call UnitAddAbility(u,'Agho')
         endif
         if(timeLeft<=0.00 and EndRemove)then
            call DeadUnitConfig(u)
            call ReleaseUnitInfo_EX(u)
            call RemoveUnit_EX(u)
         endif
      endif
      set i = i + 1
   endloop
   if(timeLeft<=0.00)then
      if(uIndex>0)then
         if(RPG_UnitData_OrbLoopTimer_00[uIndex]==GetExpiredTimer())then
            set RPG_UnitData_OrbLoopTimer_00[uIndex] = null
         elseif(RPG_UnitData_OrbLoopTimer_01[uIndex]==GetExpiredTimer())then
            set RPG_UnitData_OrbLoopTimer_01[uIndex] = null
         elseif(RPG_UnitData_OrbLoopTimer_02[uIndex]==GetExpiredTimer())then
            set RPG_UnitData_OrbLoopTimer_02[uIndex] = null
         endif
      endif
      call ReleaseTimer(GetExpiredTimer())
   endif
   set u = null
   set ou = null
endfunction

function GetMassCycleTimer takes unit ou,integer i returns timer
   local integer uIndex = GetUnitUserData(ou)
   if(uIndex>0)then
      if(i==0)then
         return RPG_UnitData_OrbLoopTimer_00[uIndex]
      elseif(i==1)then
         return RPG_UnitData_OrbLoopTimer_01[uIndex]
      elseif(i==2)then
         return RPG_UnitData_OrbLoopTimer_02[uIndex]
      endif
   endif
   return null
endfunction

function SYS_MassCycleGetTypeId takes unit ou,integer i returns integer
   local integer tmIndex
   local timer tm = GetMassCycleTimer(ou,i)
   local integer TypeId
   if(tm!=null)then
      set tmIndex = GetTimerIndex(tm)
      set tm = null
      return SYS_TimerData_I00[tmIndex]
   endif
   set tm = null
   return 0
endfunction

function SYS_MassCycleGetUnitNum takes unit ou,integer TypeId returns integer
   local integer tmIndex
   local timer tm
   local integer i = 0
   local integer CurrentUnitNum
   loop
      exitwhen(i>2)
      set tm = GetMassCycleTimer(ou,i)
      if(tm!=null)then
         set tmIndex = GetTimerIndex(tm)
         if(SYS_TimerData_I00[tmIndex]==TypeId)then
            set tm = null
            set CurrentUnitNum = SYS_TimerData_I01[tmIndex]
            return CurrentUnitNum
         endif
      endif
      set i = i + 1
   endloop
   set tm = null
   return 0
endfunction

function SYS_IsMassCycleFull takes unit ou,integer TypeId returns boolean
   local integer tmIndex
   local timer tm
   local integer i = 0
   local integer CurrentUnitNum
   local integer MaxUnitNum
   loop
      exitwhen(i>2)
      set tm = GetMassCycleTimer(ou,i)
      if(tm!=null)then
         set tmIndex = GetTimerIndex(tm)
         if(SYS_TimerData_I00[tmIndex]==TypeId)then
            set tm = null
            set CurrentUnitNum = SYS_TimerData_I01[tmIndex]
            set MaxUnitNum = SYS_TimerData_I02[tmIndex]
            if(CurrentUnitNum>=MaxUnitNum)then
               return true
            else
               return false
            endif
         endif
      endif
      set i = i + 1
   endloop
   set tm = null
   return false
endfunction

function SYS_MassCycleAddUnit takes unit ou,integer TypeId,unit u returns boolean
   local integer tmIndex
   local timer tm
   local integer i = 0
   local integer CurrentUnitNum
   local integer MaxUnitNum
   loop
      exitwhen(i>2)
      set tm = GetMassCycleTimer(ou,i)
      if(tm!=null)then
         set tmIndex = GetTimerIndex(tm)
         if(SYS_TimerData_I00[tmIndex]==TypeId)then
            set CurrentUnitNum = SYS_TimerData_I01[tmIndex]
            set MaxUnitNum = SYS_TimerData_I02[tmIndex]
            if(CurrentUnitNum<MaxUnitNum)then
               set CurrentUnitNum = CurrentUnitNum + 1
               set SYS_TimerData_I01[tmIndex] = CurrentUnitNum
               call TimerDataConfig_Unit(tmIndex,CurrentUnitNum,true,u)
               set tm = null
               return true
            endif
         endif
      endif
      set i = i + 1
   endloop
   set tm = null
   return false
endfunction

function SYS_MassCycleGetUnit takes unit ou,integer TypeId returns unit
   local integer tmIndex
   local timer tm
   local integer i = 0
   local integer CurrentUnitNum
   loop
      exitwhen(i>2)
      set tm = GetMassCycleTimer(ou,i)
      if(tm!=null)then
         set tmIndex = GetTimerIndex(tm)
         if(SYS_TimerData_I00[tmIndex]==TypeId)then
            set CurrentUnitNum = SYS_TimerData_I01[tmIndex]
            if(CurrentUnitNum>0)then
               set SYS_TempUnit[1020] = TimerDataConfig_Unit(tmIndex,CurrentUnitNum,false,null)
               call TimerDataConfig_Unit(tmIndex,CurrentUnitNum,true,null)
               set CurrentUnitNum = CurrentUnitNum - 1
               set SYS_TimerData_I01[tmIndex] = CurrentUnitNum
               set tm = null
               return SYS_TempUnit[1020]
            endif
         endif
      endif
      set i = i + 1
   endloop
   set tm = null
   return null
endfunction

function SYS_MassCycleInit takes integer TypeId,boolean EndRemove, unit ou,real time,real r,real d,real ad,real inv,integer MaxUnitNum returns timer
   local timer tm = GetTimer()
   local integer tmIndex = GetTimerIndex(tm)
   local integer uIndex = GetUnitUserData(ou)
   local real inv_ex = RConfig(inv,0.01,1.00)
   local real angleCurrent = RConfig(d,-360.00,360.00)
   local real angleAdd = ad
   local real rad = RConfig(r,100.00,2000.00)
   local integer i = 0
   local integer tempInt = 0
   if(uIndex>0 and tmIndex>0 and GetUnitState(ou,UNIT_STATE_LIFE)>0.00)then
      loop
         exitwhen(i>2)
         set tempInt = SYS_MassCycleGetTypeId(ou,i)
         if(tempInt==TypeId)then
            call ReleaseTimer(tm)
            set tm = GetMassCycleTimer(ou,i)
            set tmIndex = GetTimerIndex(tm)
            set SYS_TimerData_R04[tmIndex] = time
            set SYS_TimerData_I02[tmIndex] = MaxUnitNum
            set tm = null
            return SYS_Timer[tmIndex]
         endif
         set i = i + 1
      endloop
      set SYS_TimerData_U00[tmIndex] = ou
      set SYS_TimerData_R00[tmIndex] = angleCurrent
      set SYS_TimerData_R01[tmIndex] = angleAdd
      set SYS_TimerData_R02[tmIndex] = rad
      set SYS_TimerData_R03[tmIndex] = inv_ex
      set SYS_TimerData_R04[tmIndex] = time
      set SYS_TimerData_I00[tmIndex] = TypeId
      set SYS_TimerData_I01[tmIndex] = 0
      set SYS_TimerData_I02[tmIndex] = MaxUnitNum
      set SYS_TimerData_B00[tmIndex] = EndRemove
      if(RPG_UnitData_OrbLoopTimer_00[uIndex]==null)then
         set RPG_UnitData_OrbLoopTimer_00[uIndex] = tm
      elseif(RPG_UnitData_OrbLoopTimer_01[uIndex]==null)then
         set RPG_UnitData_OrbLoopTimer_01[uIndex] = tm
      elseif(RPG_UnitData_OrbLoopTimer_02[uIndex]==null)then
         set RPG_UnitData_OrbLoopTimer_02[uIndex] = tm
      else
         call ReleaseTimer(tm)
         set tm = null
         return null
      endif
   else
      return null
   endif
   call TimerStart(tm,inv_ex,true,function SYS_MassCycleLoop)
   set tm = null
   return SYS_Timer[tmIndex]
endfunction[/jass]
aabb.JPG

Test.rar

578 KB, 下载次数: 80

评分

参与人数 1威望 +30 收起 理由
狡猾的兔子 + 30 优秀文章

查看全部评分

 楼主| 发表于 2007-12-28 19:51:58 | 显示全部楼层
伤害目标函数,特点是:
可以为某个伤害设置“最大值,最小值,暴击系数,允许单位自定义暴击系数作用,箭矢单位,箭矢移动速度等”

[jass]function DamageUnit_Spell takes unit su,unit tu,integer DMin,integer DMax,real value returns nothing
   local real Dam = 0.00
   if(DMax>DMin and DMin>=0)then
      set Dam = I2R(GetRandomInt(DMin,DMax))
   endif
   set SYS_SpellFlag = true
   if(value>0.00 and GetUnitState(tu,UNIT_STATE_LIFE)>0.00)then
      set Dam =  Dam + value
      if(IsUnitType(tu,UNIT_TYPE_STRUCTURE))then
         set Dam = Dam*0.33
      endif
      if(GetUnitAbilityLevel(tu,'ACsk')>0 or GetUnitAbilityLevel(tu,'ACrk')>0)then
         set Dam = Dam*0.66
      elseif(GetUnitAbilityLevel(tu,'Assk')>0 and GetPlayerTechCount(GetOwningPlayer(tu),'Rers',true)>0)then
         set Dam = Dam*0.66
      endif
      call UnitDamageTarget(su,tu,Dam,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,WEAPON_TYPE_WHOKNOWS)
   elseif(value<0.00  and GetUnitState(tu,UNIT_STATE_LIFE)>0.00)then
      set Dam = Dam - value
      if(IsUnitType(tu,UNIT_TYPE_ETHEREAL))then
         set Dam = Dam*1.66
      endif
      call ShowStrPosUnitCfg(su,tu,"+"+I2S(R2I(Dam)),2,1.00,false,false,true)
      call SetUnitState(tu,UNIT_STATE_LIFE,GetUnitState(tu,UNIT_STATE_LIFE)+Dam)
      set SYS_SpellFlag = false
      call ResetDamageInfo()
   else
      call ResetDamageInfo()
   endif
endfunction
//=======================
function DamageTimedAction takes nothing returns nothing
    local real inv = 0.02
    local integer tmIndex = GetTimerIndex(GetExpiredTimer())
    local unit su = SYS_TimerData_U00[tmIndex]
    local unit tu = SYS_TimerData_U01[tmIndex]
    local unit blotU = SYS_TimerData_U02[tmIndex]
    local integer DMin = SYS_TimerData_I00[tmIndex]
    local integer DMax = SYS_TimerData_I01[tmIndex]
    local integer CR_Cfg = SYS_TimerData_I02[tmIndex]
    local integer ManaCost = SYS_TimerData_I03[tmIndex]
    local real value = SYS_TimerData_R00[tmIndex]
    local real MaxWaitTime = SYS_TimerData_R01[tmIndex]
    local real x = SYS_TimerData_R02[tmIndex]
    local real y = SYS_TimerData_R03[tmIndex]
    local real speed = SYS_TimerData_R04[tmIndex]*inv
    local real CI = SYS_TimerData_R05[tmIndex]
    local real CT_Cfg = SYS_TimerData_R06[tmIndex]
    local boolean CR_Add = SYS_TimerData_B00[tmIndex]
    local boolean CT_Add = SYS_TimerData_B01[tmIndex]
    local boolean DefendAble = SYS_TimerData_B02[tmIndex]
    local boolean KillBlot = SYS_TimerData_B03[tmIndex]
    local real tx = GetUnitX(tu)
    local real ty = GetUnitY(tu)
    local real c = Atan2(ty-y,tx-x)
    local real l = ((tx-x)*(tx-x)+((ty-y)*(ty-y)))
    if(l<=10000 or l<=speed*speed)then
       call ResetDamageInfo()
       set value = SpellValueConfig(value,CI,CR_Cfg,CR_Add,CT_Cfg,CT_Add,su,tu,DefendAble,ManaCost)
       call DamageUnit_Spell(su,tu,DMin,DMax,value)
       if(blotU!=null and KillBlot)then
          call KillUnit(blotU)
       endif
       call ReleaseTimer(GetExpiredTimer())
       return
    elseif(SYS_TimerData_R05[tmIndex]<=0)then
       if(blotU!=null and KillBlot)then
          call KillUnit(blotU)
       endif
       call ReleaseTimer(GetExpiredTimer())
       return
    endif
    set SYS_TimerData_R05[tmIndex] = SYS_TimerData_R05[tmIndex] - inv
    if(not(ty==y) and not(tx==x))then
       if(((tx-x)*(tx-x))>=1000)then
          set x = x+Cos(c)*speed
       endif
       if(((ty-y)*(ty-y))>=1000)then
          set y = y+Sin(c)*speed
       endif
       if(blotU!=null)then
          call SetUnitX(blotU,x)
          call SetUnitY(blotU,y)
       endif
       set SYS_TimerData_R02[tmIndex] = x
       set SYS_TimerData_R03[tmIndex] = y
    endif
    set su = null
    set tu = null
    set blotU = null
endfunction

function DamageTargetTimed takes unit su,unit tu,unit blotU,boolean KillBlot,real x,real y,real BlotSpeed,real MaxWaitTime,integer DMin,integer DMax,real Value,real CI,integer CR_Cfg,boolean CR_Add,real CT_Cfg,boolean CT_Add,boolean DefendAble,integer ManaCost returns nothing
    local timer tm = GetTimer()
    local integer tmIndex = GetTimerIndex(tm)
    set SYS_TimerData_U00[tmIndex] = su
    set SYS_TimerData_U01[tmIndex] = tu
    set SYS_TimerData_U02[tmIndex] = blotU
    set SYS_TimerData_I00[tmIndex] = DMin
    set SYS_TimerData_I01[tmIndex] = DMax
    set SYS_TimerData_I02[tmIndex] = CR_Cfg
    set SYS_TimerData_I03[tmIndex] = ManaCost
    set SYS_TimerData_R00[tmIndex] = Value
    set SYS_TimerData_R01[tmIndex] = MaxWaitTime
    set SYS_TimerData_R02[tmIndex] = x
    set SYS_TimerData_R03[tmIndex] = y
    set SYS_TimerData_R04[tmIndex] = BlotSpeed
    set SYS_TimerData_R05[tmIndex] = CI
    set SYS_TimerData_R06[tmIndex] = CT_Cfg
    set SYS_TimerData_B00[tmIndex] = CR_Add
    set SYS_TimerData_B01[tmIndex] = CT_Add
    set SYS_TimerData_B02[tmIndex] = DefendAble
    set SYS_TimerData_B03[tmIndex] = KillBlot
    call TimerStart(tm,0.02,true,function DamageTimedAction)
    set tm = null
endfunction[/jass]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-11-13 19:27 , Processed in 0.419602 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表