找回密码
 点一下
查看: 3898|回复: 5

RPG/ARPG 普通BOSS动作套路函数

[复制链接]
发表于 2011-3-23 17:02:55 | 显示全部楼层 |阅读模式
[jass]//call AI_UnitFlush(u) //删除单位绑定的AI函数(单位)
//call AI_UnitInit(u,atk_p) //注册单位AI(单位,攻击概率)
//call AI_UnitAIStop(u) //停止控制(单位)
//call AI_UnitAIStart(u) //开始控制(单位)
//call AI_SetRect(u,r) //设置活动区域(单位,区域)
//call AI_AddAction(u,isatk,rh,abilcd,timeout,hp,mp,dis,count,code) //添加动作函数,返回动作index
//call AI_SetActionState(u,index,rh,abilCD,timeout,hp,mp,dis,count) //修改动作属性
//call AI_RemoveAction(u,index) //删除动作函数
//call AI_SetNextAction(u,index) //设置下一个动作
//call AI_UnitAddTarget(u,target,dmg) //为单位添加一个目标(最多9个),并设置初始仇恨值(只有成为目标才会记录仇恨值)
//call AI_UnitRemoveTarget(u,target)//为单位删除一个目标
//call AI_AdjustUnitDamagePoint(u,target,value) //增加或减少单位对目标的仇恨值
//call AI_GetUnitDamagePoint(u,target) //获得单位对目标的仇恨值
//call AI_SetUnitDamagePoint(u,target,dmg) //设置单位对目标的仇恨值
//call AI_UnitHasAI(u) //单位是否注册有AI函数

// call AI_AddAction(单位,动作是否是攻击类动作,比重,动作cd,后摇时间,hp限制,mp限制,距离限制,周围单位数量限制,运行的动作函数)
// hp,mp,距离,数量的限制使用正值为要求小于该值, 负值为要求大于该值(hp,mp均为百分比)
// 在运行的函数中 可以使用以下函数得到所需数据
// AI_GetThisId() 获得正在执行的动作序号
// AI_GetThisUnit() 获得动作的执行者(单位)
// AI_GetThisRect() 获得控制范围
// AI_GetThisTarget(index) 获得当前第index号仇恨目标,如果没有则返回最低仇恨目标
// AI_GetThisAliveTarget(index) 获得当前第index号仇恨目标,要求目标存活,如果不是存活的则向前向后寻找存活目标,无合适目标返回null
// AI_GetThisTargetCount() 获得当前目标数量

globals
    hashtable bossai_ht=InitHashtable()
    integer ai_temp_rhall=0
    integer array ai_temp_rh
    integer array ai_temp_id
    integer ai_temp_Max=0
    player ai_temp_Player
    integer ai_temp_this_id=0
    unit ai_temp_this_unit=null
    rect ai_temp_this_rect=null
    //---------------
    real array quicksort_value
    unit array quicksort_unit
    integer quicksort_top=0
endglobals
function AI_GetParentKeyByUnit takes unit u returns integer
    return GetHandleId(LoadTimerHandle(bossai_ht,GetHandleId(u),10))
endfunction
function AI_GetUnitTargetByIndex takes unit u,integer index returns unit
    local integer id=AI_GetParentKeyByUnit(u)
    local integer max=LoadInteger(bossai_ht,id,5)
    if index>max then
        if max>0 then
            return LoadUnitHandle(bossai_ht,id,-max)
        else
            return null
        endif
    endif
    return LoadUnitHandle(bossai_ht,id,-index)
endfunction
function AI_GetThisId takes nothing returns integer
    return ai_temp_this_id
endfunction
function AI_GetThisUnit takes nothing returns unit
    return ai_temp_this_unit
endfunction
function AI_GetThisTarget takes integer index returns unit
    return AI_GetUnitTargetByIndex(AI_GetThisUnit(),index)
endfunction
function AI_GetThisTargetCount takes nothing returns integer
    return LoadInteger(bossai_ht,AI_GetParentKeyByUnit(AI_GetThisUnit()),5)
endfunction
function AI_GetThisAliveTarget_1 takes unit u,integer index returns unit
    local integer max=AI_GetThisTargetCount()
    local integer c=index
    local boolean back=true
    if index>max then
        if max>0 then
            set index=max
        else
            return null
        endif
    endif
    loop
        exitwhen c>max
        set u=AI_GetThisTarget(c)
        if u!=null and GetUnitState(u,UNIT_STATE_LIFE)>0 then
            return u
        endif
        if back then
            set c=c-1
            if c<=0 then
                set back=false
                set c=index+1
            endif
        else
            set c=c+1
        endif
    endloop
    return null
endfunction
function AI_GetThisAliveTarget takes integer index returns unit
    return AI_GetThisAliveTarget_1(null,index)
endfunction
function AI_GetThisRect takes nothing returns rect
    return ai_temp_this_rect
endfunction
function AI_GetUnitTargetIndex takes unit u,unit target returns integer
    local integer id=AI_GetParentKeyByUnit(u)
    local integer max=LoadInteger(bossai_ht,id,5)
    loop
        exitwhen max<=0
        if LoadUnitHandle(bossai_ht,id,-max)==target then
            return max
        endif
        set max=max-1
    endloop
    return -1
endfunction
function AI_QuickSortSwap takes integer l,integer r returns nothing
    local real tr=quicksort_value[l]
    local unit tu=quicksort_unit[l]
    set quicksort_value[l]=quicksort_value[r]
    set quicksort_unit[l]=quicksort_unit[r]
    set quicksort_value[r]=tr
    set quicksort_unit[r]=tu
    set tu=null
endfunction
function AI_QuickSortPartition takes integer l,integer r returns integer
    local boolean toleft=true
    loop
        exitwhen l>=r
        if toleft then
            if quicksort_value[r]>quicksort_value[l] then
                call AI_QuickSortSwap(l,r)
                set l=l+1
                set toleft=false
            else
                set r=r-1
            endif
        else
            if quicksort_value[r]>quicksort_value[l] then
                call AI_QuickSortSwap(l,r)
                set r=r-1
                set toleft=true
            else
                set l=l+1
            endif
        endif
    endloop
    return l
endfunction
function AI_QuickSort takes integer left,integer right returns nothing
    local integer p
    if left<right then
        set p=AI_QuickSortPartition(left,right)
        call AI_QuickSort(left,p-1)
        call AI_QuickSort(p+1,right)
    endif
endfunction
function AI_QuickSortClear takes nothing returns nothing
    set quicksort_top=0
endfunction
function AI_QuickSortAdd takes real value,unit u returns nothing
    set quicksort_top=quicksort_top+1
    set quicksort_value[quicksort_top]=value
    set quicksort_unit[quicksort_top]=u
endfunction
function AI_QuickSortStart takes nothing returns nothing
    call AI_QuickSort(1,quicksort_top)
endfunction
function AI_QuickSortGetValue takes integer index returns real
    return quicksort_value[index]
endfunction
function AI_QuickSortGetUnit takes integer index returns unit
    return quicksort_unit[index]
endfunction
function AI_UnitTargetSort takes unit u returns nothing
    local integer id=AI_GetParentKeyByUnit(u)
    local integer max=LoadInteger(bossai_ht,id,5)
    local integer c
    set c=1
    call AI_QuickSortClear() //清空排序序列
    loop
        exitwhen c>max   //添加
        call AI_QuickSortAdd(LoadReal(bossai_ht,id,-c),LoadUnitHandle(bossai_ht,id,-c))
        set c=c+1
    endloop
    call AI_QuickSortStart() //开始排序
    set c=1
    loop
        exitwhen c>max
        call SaveReal(bossai_ht,id,-c,AI_QuickSortGetValue(c))
        call SaveUnitHandle(bossai_ht,id,-c,AI_QuickSortGetUnit(c))
        set c=c+1
    endloop
endfunction
function AI_UnitFlush takes unit u returns nothing
    local integer id=AI_GetParentKeyByUnit(u)
    local integer c
    set c=LoadInteger(bossai_ht,id,1)
    loop
        exitwhen c<=0
        call DestroyTrigger(LoadTriggerHandle(bossai_ht,id,1+c*10))
        call DestroyTimer(LoadTimerHandle(bossai_ht,id,2+c*10))
        set c=c-1
    endloop
    set c=LoadInteger(bossai_ht,id,-1)
    loop
        exitwhen c<=0
        call DestroyTrigger(LoadTriggerHandle(bossai_ht,id,-(1+c*10)))
        call DestroyTimer(LoadTimerHandle(bossai_ht,id,-(2+c*10)))
        set c=c-1
    endloop
    call DestroyTrigger(LoadTriggerHandle(bossai_ht,id,3))
    call DestroyTrigger(LoadTriggerHandle(bossai_ht,id,4))
    call FlushChildHashtable(bossai_ht,id)
    call FlushChildHashtable(bossai_ht,GetHandleId(u))
endfunction
function AI_AddTempRh takes integer id,integer rh returns nothing
    set ai_temp_Max=ai_temp_Max+1
    set ai_temp_rh[ai_temp_Max]=rh
    set ai_temp_id[ai_temp_Max]=id
    set ai_temp_rhall=ai_temp_rhall+rh
endfunction
function AI_GetTempRhAndClear takes nothing returns integer
    local integer ran
    local integer min
    local integer max
    local integer c
    if ai_temp_rhall>0 then
        set ran=GetRandomInt(1,ai_temp_rhall)
    else
        return 0
    endif
    set min=1
    set max=0
    set c=1
    loop
        exitwhen c>ai_temp_Max
        set max=max+ai_temp_rh[c]
        if ran>=min and ran<=max then
            exitwhen true
        endif
        set min=max
        set c=c+1
    endloop
    set c=ai_temp_id[c]
    set ai_temp_rhall=0
    set ai_temp_Max=0
    return c
endfunction
function DistanceBetweenUnits takes unit locA, unit locB returns real
    local real dx = GetUnitX(locB) - GetUnitX(locA)
    local real dy = GetUnitY(locB) - GetUnitY(locA)
    return SquareRoot(dx * dx + dy * dy)
endfunction
function CountEnemysInRangeC takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(),ai_temp_Player)
endfunction
function CountEnemysInRange takes player p,real x,real y,real range returns integer
    local group g=CreateGroup()
    local integer c
    set ai_temp_Player=p
    call GroupEnumUnitsInRange(g,x,y,range,Condition(function CountEnemysInRangeC))
    set c=CountUnitsInGroup(g)
    call DestroyGroup(g)
    set g=null
    return c
endfunction
function AI_ActionUsable takes unit u,integer c returns boolean
    //判断id为c的动作是否可用
    local integer id=AI_GetParentKeyByUnit(u)
    local real abilcd
    local real hp
    local real mp
    local real dis
    local integer count
    local integer amount
    if c==0 then
        return false
    elseif c>0 then
        if c>LoadInteger(bossai_ht,id,1) then
            return false
        endif
        set abilcd=TimerGetRemaining(LoadTimerHandle(bossai_ht,id,2+c*10))
        set hp=LoadReal(bossai_ht,id,3+c*10)
        set mp=LoadReal(bossai_ht,id,4+c*10)
        set dis=LoadReal(bossai_ht,id,5+c*10)
        set count=LoadInteger(bossai_ht,id,2+c*10)
    else
        if -c>LoadInteger(bossai_ht,id,-1) then
            return false
        endif
        set abilcd=TimerGetRemaining(LoadTimerHandle(bossai_ht,id,-2+c*10))
        set hp=LoadReal(bossai_ht,id,-3+c*10)
        set mp=LoadReal(bossai_ht,id,-4+c*10)
        set dis=LoadReal(bossai_ht,id,-5+c*10)
        set count=LoadInteger(bossai_ht,id,-2+c*10)
    endif
    if abilcd>0 then
        debug call BJDebugMsg("技能CD="+R2S(abilcd))
        debug call BJDebugMsg("返回false")
        return false  //技能cd
    elseif (hp>0 and GetUnitStatePercent(u,UNIT_STATE_LIFE,UNIT_STATE_MAX_LIFE)>hp) or (hp<0 and GetUnitStatePercent(u,UNIT_STATE_LIFE,UNIT_STATE_MAX_LIFE)<-hp) then
        debug call BJDebugMsg("生命超限")
        return false  //生命值限制
    elseif (mp>0 and GetUnitStatePercent(u,UNIT_STATE_MANA,UNIT_STATE_MAX_MANA)>mp) or (mp<0 and GetUnitStatePercent(u,UNIT_STATE_MANA,UNIT_STATE_MAX_MANA)<-mp) then
        debug call BJDebugMsg("魔法超限")
        return false  //魔法值限制
    elseif (dis>0 and DistanceBetweenUnits(u,AI_GetUnitTargetByIndex(u,1))>dis) or (dis<0 and DistanceBetweenUnits(u,AI_GetUnitTargetByIndex(u,1))<-dis) then
        debug call BJDebugMsg("距离超限")
        return false  //与主目标距离限制
    else
        if count!=0 then
            set amount=CountEnemysInRange(GetOwningPlayer(u),GetUnitX(u),GetUnitY(u),dis)
            if (count>0 and amount>count) or (count<0 and amount<-count) then
                return false //范围内单位限制
            endif
        endif
    endif
    return true
endfunction
function AI_SetNextAction takes unit u,integer index returns nothing
    call SaveInteger(bossai_ht,AI_GetParentKeyByUnit(u),3,index)
endfunction
function AI_TimerAction takes nothing returns nothing
    local integer id=GetHandleId(GetExpiredTimer())
    local integer c
    local integer cend
    //<判断/改变目标>
    set c=LoadInteger(bossai_ht,id,3)
    if c!=0 then //下一个动作index
        call SaveInteger(bossai_ht,id,3,0) //取消下一个动作index
        if AI_ActionUsable(LoadUnitHandle(bossai_ht,id,0),c) then
            call SaveInteger(bossai_ht,id,0,c) //记录当前动作
            call TimerStart(LoadTimerHandle(bossai_ht,id,(2+c*10)),LoadReal(bossai_ht,id,(1+c*10)),false,null) //开启动作冷却计时器
            call TimerStart(GetExpiredTimer(),LoadReal(bossai_ht,id,(2+c*10)),false,function AI_TimerAction) //开启跳转计时器
            set ai_temp_this_id=c
            set ai_temp_this_unit=LoadUnitHandle(bossai_ht,id,0)
            set ai_temp_this_rect=LoadRectHandle(bossai_ht,id,1)
            call AI_UnitTargetSort(ai_temp_this_unit)
            call TriggerEvaluate(LoadTriggerHandle(bossai_ht,id,1+c*10))
            return
        endif
    endif
    if GetRandomReal(0.0,1.0)<LoadReal(bossai_ht,id,1) then
        //攻击动作
        set c=1
        set cend=LoadInteger(bossai_ht,id,1)
        loop
            exitwhen c>cend
            if AI_ActionUsable(LoadUnitHandle(bossai_ht,id,0),c) then //可使用判断
                call AI_AddTempRh(c,LoadInteger(bossai_ht,id,1+c*10))
            endif
            set c=c+1
        endloop
        set c=AI_GetTempRhAndClear()
        if c==0 then
            call TimerStart(GetExpiredTimer(),1,false,function AI_TimerAction) //直接跳转
            debug call BJDebugMsg("无可执行动作 1秒后跳转")
            return
        endif
        call SaveInteger(bossai_ht,id,0,c) //记录当前动作
        call TimerStart(LoadTimerHandle(bossai_ht,id,(2+c*10)),LoadReal(bossai_ht,id,(1+c*10)),false,null) //开启动作冷却计时器
        call TimerStart(GetExpiredTimer(),LoadReal(bossai_ht,id,(2+c*10)),false,function AI_TimerAction) //开启跳转计时器
        set ai_temp_this_id=c
        set ai_temp_this_unit=LoadUnitHandle(bossai_ht,id,0)
        set ai_temp_this_rect=LoadRectHandle(bossai_ht,id,1)
        call AI_UnitTargetSort(ai_temp_this_unit) //立即排序
        call TriggerEvaluate(LoadTriggerHandle(bossai_ht,id,1+c*10))
    else
        //防御动作
        set c=1
        set cend=LoadInteger(bossai_ht,id,-1)
        loop
            exitwhen c>cend
            if AI_ActionUsable(LoadUnitHandle(bossai_ht,id,0),-c) then
                call AI_AddTempRh(c,LoadInteger(bossai_ht,id,-(1+c*10)))
            endif
            set c=c+1
        endloop
        set c=AI_GetTempRhAndClear()
        if c==0 then
            call TimerStart(GetExpiredTimer(),1,false,function AI_TimerAction) //直接跳转
            debug call BJDebugMsg("无可执行动作 1秒后跳转")
            return
        endif
        call SaveInteger(bossai_ht,id,0,-c)
        call TimerStart(LoadTimerHandle(bossai_ht,id,-(2+c*10)),LoadReal(bossai_ht,id,-(1+c*10)),false,null)
        call TimerStart(GetExpiredTimer(),LoadReal(bossai_ht,id,-(2+c*10)),false,function AI_TimerAction)
        set ai_temp_this_id=-c
        set ai_temp_this_unit=LoadUnitHandle(bossai_ht,id,0)
        set ai_temp_this_rect=LoadRectHandle(bossai_ht,id,1)
        call AI_UnitTargetSort(ai_temp_this_unit) //立即排序
        call TriggerEvaluate(LoadTriggerHandle(bossai_ht,id,-1-c*10))
    endif
endfunction
function AI_UnitAIStop takes unit u returns nothing
    //停止控制单位
    call PauseTimer(LoadTimerHandle(bossai_ht,GetHandleId(u),10))
endfunction
function AI_UnitAIStart takes unit u returns nothing
    //开始控制单位
    if HaveSavedBoolean(bossai_ht,AI_GetParentKeyByUnit(u),0) then
        call TimerStart(LoadTimerHandle(bossai_ht,GetHandleId(u),10),0.0,false,function AI_TimerAction)
    else
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"|Cffff0000BOSS_AI_Error: UNIT_AI_NOT_DEFINED|r")
    endif
endfunction
function AI_UnitDeathAction takes nothing returns nothing
    local unit u=GetTriggerUnit()
    if HaveSavedBoolean(bossai_ht,AI_GetParentKeyByUnit(u),0) then
        call AI_UnitAIStop(u)
        call AI_UnitFlush(u)
    endif
    set u=null
endfunction
function AI_GetUnitDamagePoint takes unit u,unit target returns real
    local integer id=AI_GetParentKeyByUnit(u)
    local integer c=AI_GetUnitTargetIndex(u,target)
    if c>0 then
        return LoadReal(bossai_ht,id,-c)
    endif
    return -1.
endfunction
function AI_SetUnitDamagePoint takes unit u,unit target,real dmg returns nothing
    local integer id=AI_GetParentKeyByUnit(u)
    local integer c=AI_GetUnitTargetIndex(u,target)
    if c>0 then
        call SaveReal(bossai_ht,id,-c,dmg)
    endif
endfunction
function AI_AdjustUnitDamagePoint takes unit u,unit target,real dmg returns nothing
    local integer id=AI_GetParentKeyByUnit(u)
    local integer c=AI_GetUnitTargetIndex(u,target)
    if c>0 then
        call SaveReal(bossai_ht,id,-c,LoadReal(bossai_ht,id,-c)+dmg)
    endif
endfunction
function AI_UnitDamageAction takes nothing returns nothing
    call AI_AdjustUnitDamagePoint(GetTriggerUnit(),GetEventDamageSource(),GetEventDamage())
endfunction
function AI_UnitHasAI takes unit u returns boolean
    return HaveSavedBoolean(bossai_ht,AI_GetParentKeyByUnit(u),0)
endfunction
function AI_UnitAddTarget takes unit u,unit target,real dmg returns boolean
    //为单位添加一个目标,是目标才会积累仇恨值,目标最多9个,添加成功返回true
    local integer id=AI_GetParentKeyByUnit(u)
    local integer max=LoadInteger(bossai_ht,id,5)
    if max>=9 then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"|cffff0000AI_UnitAddTarget_Error: COUNTS_OVER_MAX|r")
        return false
    elseif AI_GetUnitTargetIndex(u,target)!=-1 then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"|cffff0000AI_UnitAddTarget_Error: TARGET_EXIST|r")
        return false
    endif
    set max=max+1
    call SaveInteger(bossai_ht,id,5,max)
    call SaveUnitHandle(bossai_ht,id,-max,target)
    call SaveReal(bossai_ht,id,-max,dmg)
    call AI_UnitTargetSort(u) //排序
    return true
endfunction
function AI_UnitRemoveTarget takes unit u,unit target returns boolean
    //为单位删除一个目标,是目标才会积累仇恨值,目标最多9个,删除成功返回true,不成功(不存在)返回false
    local integer id=AI_GetParentKeyByUnit(u)
    local integer max=LoadInteger(bossai_ht,id,5)
    local integer c
    if max<=0 then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"|cffff0000AI_UnitRemoveTarget_Error: COUNTS_UNDER_MIN|r")
        return false
    else
        set c=AI_GetUnitTargetIndex(u,target)
        if c==-1 then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"|cffff0000AI_UnitRemoveTarget_Error: CANNOT_FIND_THIS_TARGET|r")
        endif
        return false
    endif
    call SaveUnitHandle(bossai_ht,id,-c,LoadUnitHandle(bossai_ht,id,-max))
    call SaveReal(bossai_ht,id,-c,LoadReal(bossai_ht,id,-max))
    call SaveInteger(bossai_ht,id,5,max-1)
    call AI_UnitTargetSort(u) //排序
    return true
endfunction
function AI_UnitInit takes unit u,real atk_p returns nothing
    //单位注册AI  单位,攻击/防御比,初始目标单位
    local timer t=CreateTimer()
    local integer tid=GetHandleId(t)
    local trigger trig=CreateTrigger()
    call SaveUnitHandle(bossai_ht,tid,0,u) //操作的单位
    call SaveReal(bossai_ht,tid,1,atk_p)  //攻击/防御比
    call SaveBoolean(bossai_ht,tid,0,true) //指示 AI存在
    call SaveTimerHandle(bossai_ht,GetHandleId(u),10,t) //将计时器绑定到单位
    call TriggerRegisterDeathEvent(trig,u) //单位死亡时自动清理ai数据
    call TriggerAddCondition(trig,Condition(function AI_UnitDeathAction))
    call SaveTriggerHandle(bossai_ht,tid,3,trig)  //记录单位死亡触发器
    set trig=CreateTrigger()
    call TriggerRegisterUnitEvent(trig,u,EVENT_UNIT_DAMAGED)
    call TriggerAddCondition(trig,Condition(function AI_UnitDamageAction))
    call SaveTriggerHandle(bossai_ht,tid,4,trig)  //记录单位伤害触发器
    call SaveInteger(bossai_ht,tid,1,0)
    call SaveInteger(bossai_ht,tid,2,0)
    call SaveInteger(bossai_ht,tid,-1,0)
    call SaveInteger(bossai_ht,tid,-2,0)
    call SaveInteger(bossai_ht,tid,0,0)  //当前执行动作
    call SaveInteger(bossai_ht,tid,3,0)  //下一个动作
    set t=null
    set trig=null
endfunction
function AI_SetRect takes unit u,rect r returns nothing
    //添加行动区域  单位,区域
    call SaveRectHandle(bossai_ht,AI_GetParentKeyByUnit(u),1,r) //行动范围
endfunction
function AI_RemoveAction takes unit u,integer index returns boolean
    //删除序号为 index的动作
    local integer id
    local integer max
    local integer n
    local integer nn
    if index==0 then
        return false
    elseif index>0 then //攻击类
        set id=AI_GetParentKeyByUnit(u)
        set max=LoadInteger(bossai_ht,id,1)
        if index>max then
            return false
        endif
        set n=10*index
        set nn=10*max
        call SaveInteger(bossai_ht,id,2,LoadInteger(bossai_ht,id,2)-LoadInteger(bossai_ht,id,1+n))//比重减少
        call SaveInteger(bossai_ht,id,1,max-1) //动作数-1
        //数据转移
        call SaveInteger(bossai_ht,id,1+n,LoadInteger(bossai_ht,id,1+nn))
        call SaveInteger(bossai_ht,id,2+n,LoadInteger(bossai_ht,id,2+nn))
        call SaveReal(bossai_ht,id,1+n,LoadReal(bossai_ht,id,1+nn))
        call SaveReal(bossai_ht,id,2+n,LoadReal(bossai_ht,id,2+nn))
        call SaveReal(bossai_ht,id,3+n,LoadReal(bossai_ht,id,3+nn))
        call SaveReal(bossai_ht,id,4+n,LoadReal(bossai_ht,id,4+nn))
        call SaveReal(bossai_ht,id,5+n,LoadReal(bossai_ht,id,5+nn))
        call DestroyTrigger(LoadTriggerHandle(bossai_ht,id,1+n))
        call SaveTriggerHandle(bossai_ht,id,1+n,LoadTriggerHandle(bossai_ht,id,1+nn))
        call DestroyTimer(LoadTimerHandle(bossai_ht,id,2+n))
        call SaveTimerHandle(bossai_ht,id,2+n,LoadTimerHandle(bossai_ht,id,2+nn))
        return true
    else
        set id=AI_GetParentKeyByUnit(u)
        set max=LoadInteger(bossai_ht,id,-1)
        set index=-index
        if index>max then
            return false
        endif
        set n=-10*index
        set nn=-10*max
        call SaveInteger(bossai_ht,id,-2,LoadInteger(bossai_ht,id,2)-LoadInteger(bossai_ht,id,1+n))//比重减少
        call SaveInteger(bossai_ht,id,-1,max-1) //动作数-1
        //数据转移
        call SaveInteger(bossai_ht,id,-1+n,LoadInteger(bossai_ht,id,-1+nn))
        call SaveInteger(bossai_ht,id,-2+n,LoadInteger(bossai_ht,id,-2+nn))
        call SaveReal(bossai_ht,id,-1+n,LoadReal(bossai_ht,id,-1+nn))
        call SaveReal(bossai_ht,id,-2+n,LoadReal(bossai_ht,id,-2+nn))
        call SaveReal(bossai_ht,id,-3+n,LoadReal(bossai_ht,id,-3+nn))
        call SaveReal(bossai_ht,id,-4+n,LoadReal(bossai_ht,id,-4+nn))
        call SaveReal(bossai_ht,id,-5+n,LoadReal(bossai_ht,id,-5+nn))
        call DestroyTrigger(LoadTriggerHandle(bossai_ht,id,-1+n))
        call SaveTriggerHandle(bossai_ht,id,-1+n,LoadTriggerHandle(bossai_ht,id,-1+nn))
        call DestroyTimer(LoadTimerHandle(bossai_ht,id,-2+n))
        call SaveTimerHandle(bossai_ht,id,-2+n,LoadTimerHandle(bossai_ht,id,-2+nn))
        return true
    endif
endfunction
function AI_AddAction takes unit u,boolean isatk,integer rh,real abilCD,real timeout,real hp,real mp,real dis,integer count,code handlerFunc returns integer
    //添加动作 返回动作序号
    local integer id=AI_GetParentKeyByUnit(u)
    local integer n
    local trigger trig=CreateTrigger()  
    if isatk then
        call SaveInteger(bossai_ht,id,1,1+LoadInteger(bossai_ht,id,1)) //最大动作数
        call SaveInteger(bossai_ht,id,2,rh+LoadInteger(bossai_ht,id,2)) //总比重
        set n=10*LoadInteger(bossai_ht,id,1)
        call SaveInteger(bossai_ht,id,1+n,rh)
        call SaveInteger(bossai_ht,id,2+n,count)
        call SaveReal(bossai_ht,id,1+n,abilCD)
        call SaveReal(bossai_ht,id,2+n,timeout)
        call SaveReal(bossai_ht,id,3+n,hp)
        call SaveReal(bossai_ht,id,4+n,mp)
        call SaveReal(bossai_ht,id,5+n,dis)
        call SaveTriggerHandle(bossai_ht,id,1+n,trig)
        call SaveTimerHandle(bossai_ht,id,2+n,CreateTimer())
        set id=LoadInteger(bossai_ht,id,1)
    else
        call SaveInteger(bossai_ht,id,-1,1+LoadInteger(bossai_ht,id,-1))
        call SaveInteger(bossai_ht,id,-2,rh+LoadInteger(bossai_ht,id,-2))
        set n=-10*LoadInteger(bossai_ht,id,-1)
        call SaveInteger(bossai_ht,id,-1+n,rh)
        call SaveInteger(bossai_ht,id,-2+n,count)
        call SaveReal(bossai_ht,id,-1+n,abilCD)
        call SaveReal(bossai_ht,id,-2+n,timeout)
        call SaveReal(bossai_ht,id,-3+n,hp)
        call SaveReal(bossai_ht,id,-4+n,mp)
        call SaveReal(bossai_ht,id,-5+n,dis)
        call SaveTriggerHandle(bossai_ht,id,-1+n,trig)
        call SaveTimerHandle(bossai_ht,id,-2+n,CreateTimer())
        set id=-LoadInteger(bossai_ht,id,-1)
    endif
    call TriggerAddCondition(trig,Condition(handlerFunc))
    set trig=null
    return id //动作id
endfunction
function AI_SetActionState takes unit u,integer index,integer rh,real abilCD,real timeout,real hp,real mp,real dis,integer count returns nothing
    //修改序号为index的动作
    local integer id=AI_GetParentKeyByUnit(u)
    local integer n
    local integer max
    if index==0 then
        return
    elseif index>0 then
        set max=LoadInteger(bossai_ht,id,1)
        if index>max then
            return
        endif
        set n=10*index
        call SaveInteger(bossai_ht,id,2,LoadInteger(bossai_ht,id,2)-LoadInteger(bossai_ht,id,1+n)+rh) //总比重改变
        call SaveInteger(bossai_ht,id,1+n,rh)
        call SaveInteger(bossai_ht,id,2+n,count)
        call SaveReal(bossai_ht,id,1+n,abilCD)
        call SaveReal(bossai_ht,id,2+n,timeout)
        call SaveReal(bossai_ht,id,3+n,hp)
        call SaveReal(bossai_ht,id,4+n,mp)
        call SaveReal(bossai_ht,id,5+n,dis)
    else
        set index=-index
        set max=LoadInteger(bossai_ht,id,-1)
        if index>max then
            return
        endif
        set n=-10*index
        call SaveInteger(bossai_ht,id,-2,LoadInteger(bossai_ht,id,-2)-LoadInteger(bossai_ht,id,-1+n)+rh)
        call SaveInteger(bossai_ht,id,-1+n,rh)
        call SaveInteger(bossai_ht,id,-2+n,count)
        call SaveReal(bossai_ht,id,-1+n,abilCD)
        call SaveReal(bossai_ht,id,-2+n,timeout)
        call SaveReal(bossai_ht,id,-3+n,hp)
        call SaveReal(bossai_ht,id,-4+n,mp)
        call SaveReal(bossai_ht,id,-5+n,dis)
    endif
endfunction[/jass]
发表于 2011-3-24 04:47:19 | 显示全部楼层
说说用法嘛~
回复

使用道具 举报

发表于 2011-3-26 23:20:52 | 显示全部楼层
感谢分享。。。
回复

使用道具 举报

发表于 2011-3-26 23:35:37 | 显示全部楼层
感谢分享。。。话说木有演示神马的吗?代码我复制过去前面有数字有600+行前面的数字一行行去掉,,没这个耐心。。。。
回复

使用道具 举报

 楼主| 发表于 2011-3-27 01:04:12 | 显示全部楼层
额, 最上边不是有个复制代码么= =.
这个函数只是个模版呢, 具体动作什么的还要自己写,
回复

使用道具 举报

发表于 2018-8-15 09:48:52 | 显示全部楼层
这个模板很棒0.0
谢谢楼主
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-26 15:59 , Processed in 0.072380 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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