|
【传说中的施法条系统】
【冰法技能系统】
【冰法天赋系统】
【这个是复活系统】
既然有人反感。装逼的话就不说了 留几张图吧。
顺便留个BUFF/DEBUFF系统,希望高手指点。
基本上魔兽世界中所有的DEBUFF和一些属性参数修改型的BUFF 都用这一条函数就能实现了
因为技能系统也是完全重做,技能数据也是完全绑定在哈希表中的。
因此这个函数还可以 影响技能数据。比如我的一个BUFF需要增加人物的寒冰箭技能伤害500点 也是这一个函数就OK了
再配合自己做的事件处理系统 添加一个BUFF结束事件的捕捉
比如生命绽放这种BUFF效果(每秒回血,可叠加3次 效果结束后 会额外治疗目标XX点 回复施法者XX点魔法) 也用不了几行调用
function AddBuff takes unit sbj,  //Buff释放者
                                         unit target,//Buff目标
                                         integer buffid,// buff马甲的技能ID (我用一个光环技能当作BUFF 并且塞到隐藏的魔法书里 来达到BUFF马甲的效果 这个ID是隐藏该BUFF的魔法书ID)
                                         integer attribid,//减少/增加的属性索引大于0的都是在人物数据绑定里的子索引 ,数据绑定见下文 。-1力量 -2 敏捷 -3 智力 -4 生命值 -5 魔法值
                                         real value,//改变的值
                                         real mode ,//改变的模式  1 是增加 -1是减少
                                         boolean isOverlay,//是否允许重叠。如 每秒掉100血的DOT 再加一个的话就会每秒掉200
                                         real rate,//DOT 或者HOT的暴击几率
                                         real timeslice,//时间片持续时间 对于持续性BUFF 意义是 指定的属性改变持续XX时间(此时时间片个数一定要为1) 对于DOT或者HOT 意义是 每一跳的时间 例如 腐蚀术 每3秒造成138点伤害 这里timeslice就是3
                                         integer slicenum ,//时间片个数 就是对于DOT HOT来说 持续多少跳 也就是说该BUFF 持续总时间为 timeslice*slicenum
                                         effect ef //该BUFF带有的魔法效果 用于BUFF结束后的删除 没有的话直接给NULL就行了
returns nothing
数据绑定
人物数据绑定
哈希表udg_hsUnitsBind
主索引= 单位的handle值
子索引 定义如下
  //1 攻击强度
    //2 近战暴击
    //3 法术伤害
    //4 法术爆击
    //5 躲闪几率
    //6 格挡几率
    //7 格挡值
    //8 护甲穿透  
    //9 法术急速
    // 11-施法条计时器
   // 12-施法条计时器 受攻击后退格数
    //14 护甲值
    //15 魔法抗性
    //21-22攻击力
    //23 攻击力附加
    //30 天赋点
    //31剩余天赋点
    //50+ 人物事件标志
    //60 人物Buff栈指针 61-79 人物Buff栈空间 用于记录 人物身上现在有的BUFF计时器 主要用于清除或者继续叠加人物身上指定个数的BUFF(如净化技能)
    //80 人物DeBuff栈指针 81-99 人物DeBuff栈空间
Buff马甲与具体BUFF绑定
(弄这个是为了 删除BUFF效果更好 因为如果只删除隐藏BUFF的魔法书 人物身上的BUFF图标总要延迟0.5-1秒才消失 所以我一用绑定 删除隐藏BUFF的魔法书同时 也删除对应(绑定)的BUFF)
哈希表 udg_hsExtraBind
主索引=1
子索引 隐藏BUFF的魔法书
存入值 隐藏BUFF的魔法书对应的BUFFid
BUFF信息与相应的计时器绑定
(buff的所有信息是与计时器绑定的 计时器虽然是临时变量申请的 但是会保存到人物绑定里的BUFF&DEBUFF栈里)
哈希表 udg_hsTimerBind
主索引= timer的handle值
子索引 定义如下
0 BUFF释放者
1 BUFF释放目标
2 BUFFid
3 BUFF改动目标属性的索引
4 BUFF改变属性的值
5 时间片个数
6 HOT 或DOT的 暴击几率
7 BUFF特效模型
8 BUFF改动模式
[jass]
function AddBuffIcon takes unit sbj,integer buffid returns nothing//给人物增加 BUFF马甲
if(buffid!=0) then
    call UnitAddAbilityBJ( buffid, sbj )
    call SetPlayerAbilityAvailableBJ( false, buffid, GetOwningPlayer(sbj))
  endif
endfunction  
function ClearBuffIcon takes unit sbj,integer buffid returns nothing//删除人物的BUFF马甲
if(buffid!=0)then
  call  UnitRemoveAbilityBJ( buffid, sbj )
  call  UnitRemoveBuffBJ(LoadIntegerBJ(buffid,1,gl_hsExtra),sbj)
endif
endfunction
////////////清楚BUFF效果////////////////
function DestroyBuff takes timer t returns nothing  
local integer attribid=LoadIntegerBJ(3,YDWEGetTimerID(t), udg_hsTimerBind )//更改属性的索引
local integer buffid=LoadIntegerBJ(2,YDWEGetTimerID(t), udg_hsTimerBind )//BUFF的ID 其实是隐藏BUFF的魔法书的ID
local unit u=LoadUnitHandleBJ(1,YDWEGetTimerID(t), udg_hsTimerBind)  
local real value=LoadRealBJ(4,YDWEGetTimerID(t), udg_hsTimerBind )
local unit tar=LoadUnitHandleBJ(1,YDWEGetTimerID(t), udg_hsTimerBind )
local real curvalue
local real mode=LoadRealBJ(8,YDWEGetTimerID(t), udg_hsTimerBind )
//恢复人物被改动的属性if(attribid==-1) then
    set curvalue=I2R(GetHeroStr(tar,true))
    call SetHeroStr(tar,R2I(curvalue-value*mode),true)
  elseif(attribid==-2)then
    set curvalue=I2R(GetHeroAgi(tar,true))
    call SetHeroAgi(tar,R2I(curvalue-value*mode),true)
  elseif(attribid==-3) then
    set curvalue=I2R(GetHeroInt(tar,true))
    call SetHeroInt(tar,R2I(curvalue-value*mode),true)
  elseif(attribid>0) then
    set curvalue=LoadRealBJ(attribid,YDWEGetUnitID(tar),udg_hsUnits )
    call SaveRealBJ(curvalue-value*mode,attribid,YDWEGetUnitID(tar), udg_hsUnits )
endif
call ClearBuffIcon(u,buffid)
call FlushChildHashtableBJ(YDWEGetTimerID(t), udg_hsTimerBind )
call DestroyTimer(t)
call DestroyEffect(LoadEffectHandleBJ(7,YDWEGetTimerID(t), udg_hsTimerBind ))
call SaveTimerHandleBJ(null,buffid,YDWEGetUnitID(u), udg_hsUnits ) //将BUFF计时器的保存位置清空 下文会讲
endfunction
//////////////////////////////////////////////////////////
////////////清除掉人物身上C个 BUFF或者DEBUFF/////
function DefuseBuff takes unit subject,integer c ,boolean isDebuff returns nothing
local integer l
local integer sp// 人物BUFF DEBUFF栈顶指针
local integer index
local timer t
if(isDebuff) then
  set l=80
else  
  set l=60
endif
  set sp=LoadIntegerBJ(l,GetHandleIdBJ(subject),udg_hsUnits )
  if(sp==0) then
  return
  endif
if(c>sp-1) then
set c=sp
endif
loop  
exitwhen(c==0)
set index=LoadIntegerBJ(l+sp,GetHandleIdBJ(subject),udg_hsUnits)
set sp=sp-1
call SaveIntegerBJ(sp,l,GetHandleIdBJ(subject),udg_hsUnits )
call DestroyBuff(LoadTimerHandleBJ(index,GetHandleIdBJ(subject),udg_hsUnits ))
set c=c-1
endloop
endfunction
  
  
/////////////////////////////////////////////////////
////////////BUFF动作 ////////////////////////////
function BuffAction takes nothing returns nothing
local unit sbj=LoadUnitHandleBJ(0,YDWEGetTimerID(GetExpiredTimer()), udg_hsTimerBind )
local unit tar=LoadUnitHandleBJ(1,YDWEGetTimerID(GetExpiredTimer()), udg_hsTimerBind )
local integer attribid=LoadIntegerBJ(3,YDWEGetTimerID(GetExpiredTimer()), udg_hsTimerBind )
local real value=LoadRealBJ(4,YDWEGetTimerID(GetExpiredTimer()), udg_hsTimerBind )
local real curvalue
local integer n=LoadIntegerBJ(5,YDWEGetTimerID(GetExpiredTimer()), udg_hsTimerBind )
local real rate=LoadRealBJ(6,YDWEGetTimerID(GetExpiredTimer()), udg_hsTimerBind )
local real mode=LoadRealBJ(8,YDWEGetTimerID(GetExpiredTimer()), udg_hsTimerBind )
  
  if(attribid==-4) then
       if(OddsTest(rate)==1) then//暴击判断 OddsTest()是我自己写的几率发生器 如果几率命中则返回1
           set value=value*1.5
           call DisplayTextTag(I2S(R2I(value)),sbj,tar,3+R2I(mode),true)//这是我自己写的显示伤害的封装函数 可以忽略
       else
           call DisplayTextTag(I2S(R2I(value)),sbj,tar,3+R2I(mode),false)
       endif
       set curvalue=GetUnitState(tar,UNIT_STATE_LIFE)
       if(mode==1) then//如果 是加血则 直接设置生命值
           call SetUnitState(tar,UNIT_STATE_LIFE,curvalue+value)
       else //如果是减血 则造成伤害
           call UnitDamageTargetBJ(sbj,tar,value,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC)
       endif
    
  elseif(attribid==-5) then
    set curvalue=GetUnitState(tar,UNIT_STATE_MANA)
    call SetUnitState(tar,UNIT_STATE_MANA,curvalue+value*mode)
    call DisplayTextTag(I2S(R2I(value)),sbj,tar,3,false)
  
endif
  
set n=n-1
if(n==0) then //时间片数量用尽 BUFF结束
call DestroyBuff(GetExpiredTimer())
else  
call SaveIntegerBJ(n,5,YDWEGetTimerID(GetExpiredTimer()), udg_hsTimerBind )
endif
set sbj=null
set tar=null
endfunction
  
///////////////////////////////////////////
/////////////////主函数/////////////////
function AddBuff takes unit sbj,unit target,integer buffid,integer attribid,real value,real mode ,boolean isOverlay,real rate,real timeslice,integer slicenum ,effect ef returns nothing
  
  local real oldvalue
  local timer tm=CreateTimer()
  local timer rtm=LoadTimerHandleBJ(buffid,YDWEGetUnitID(target), udg_hsUnits )// rtm 用来取得人物身上是已有的BUFF的计时器 索引是BUFFID 会在后面判断rtm是否为空 也就是判断 该目标身上是否已经存在该BUFF (然后再进行相关叠加处理)
  local integer index
  if(mode==1) then
  set index=60  
  else  
  set index=80
  endif
  
  
  if(rtm==null) then //说明是新BUFF
  
   if(attribid==-1) then
    set oldvalue=I2R(GetHeroStr(target,true))
    call SetHeroStr(target,R2I(oldvalue+value*mode),true)
  elseif(attribid==-2)then
    set oldvalue=I2R(GetHeroAgi(target,true))
    call SetHeroAgi(target,R2I(oldvalue+value*mode),true)
  elseif(attribid==-3) then
    set oldvalue=I2R(GetHeroInt(target,true))
    call SetHeroInt(target,R2I(oldvalue+value*mode),true)
  elseif(attribid>0) then
    set oldvalue=LoadRealBJ(attribid,YDWEGetUnitID(target),udg_hsUnits )
    call SaveRealBJ(oldvalue+value*mode,attribid,YDWEGetUnitID(target), udg_hsUnits )
  endif
  call SaveUnitHandleBJ(sbj,0,YDWEGetTimerID(tm), udg_hsTimerBind )
  call SaveUnitHandleBJ(target,1,YDWEGetTimerID(tm), udg_hsTimerBind )
  call SaveIntegerBJ(buffid,2,YDWEGetTimerID(tm), udg_hsTimerBind )
  call SaveIntegerBJ(attribid,3,YDWEGetTimerID(tm), udg_hsTimerBind )
  call SaveRealBJ(value,4,YDWEGetTimerID(tm), udg_hsTimerBind )
  call SaveIntegerBJ(slicenum,5,YDWEGetTimerID(tm), udg_hsTimerBind )
  call SaveRealBJ(rate,6,YDWEGetTimerID(tm), udg_hsTimerBind )
  call SaveEffectHandleBJ(ef,7,YDWEGetTimerID(tm), udg_hsTimerBind )
  call SaveRealBJ(mode,8,YDWEGetTimerID(tm), udg_hsTimerBind )
  call SaveTimerHandleBJ(tm,buffid,YDWEGetUnitID(target), udg_hsUnits )
  call AddBuffIcon(target,buffid)
//保存到人物的DEBUFF BUFF栈    BUFF栈中存放的其实是BUFFID 然后 再通过BUFFID索引到该BUFF的计时器call SaveIntegerBJ(LoadIntegerBJ(index,GetHandleIdBJ(target),udg_hsUnits )+1,index,GetHandleIdBJ(target),udg_hsUnits )
    call SaveIntegerBJ(buffid,index+LoadIntegerBJ(index,GetHandleIdBJ(target),udg_hsUnits ),YDWEGetUnitID(target), udg_hsUnits )
   call TimerStart(tm,timeslice,true,function BuffAction)
  
else  
  
   if(isOverlay) then //如果允许覆盖 则继续改变相应的属性值 并更新 数据绑定4中的value
      if(attribid==-1) then
        set oldvalue=I2R(GetHeroStr(target,true))
        call SetHeroStr(target,R2I(oldvalue+value*mode),true)
      elseif(attribid==-2)then
        set oldvalue=I2R(GetHeroAgi(target,true))
        call SetHeroAgi(target,R2I(oldvalue+value*mode),true)
      elseif(attribid==-3) then
        set oldvalue=I2R(GetHeroInt(target,true))
        call SetHeroInt(target,R2I(oldvalue+value*mode),true)
      elseif(attribid>0) then
        set oldvalue=LoadRealBJ(attribid,YDWEGetUnitID(target),udg_hsUnits )
        call SaveRealBJ(oldvalue+value*mode,attribid,YDWEGetUnitID(target), udg_hsUnits )
        endif
        call SaveRealBJ(value+LoadRealBJ(4,YDWEGetTimerID(rtm), udg_hsTimerBind ),4,YDWEGetTimerID(rtm), udg_hsTimerBind )
      
   endif
//否则的话只会刷新时间片数量 重新开启计时器
call SaveIntegerBJ(slicenum,5,YDWEGetTimerID(rtm), udg_hsTimerBind )
call TimerStart(rtm,timeslice,true,function BuffAction)
  endif
set tm=null
set rtm=null
  
  endfunction
  
  //下面只是封装两个 针对常用简单用处的外部接口函数 减少一些不常用的参数 是函数调用方便//功能是 仅仅减少或者增加目标的属性 且不能叠加没有特效
  function AddAttribBuff takes unit obj,integer buffid,integer attribid,real val,real duration returns nothing
  call AddBuff(obj,obj,buffid,attribid,val,1,false,0,duration,1,null)
  endfunction  
  function  ReduceTargetAttrib takes unit obj,integer buffid,integer attribid,real val,real duration returns nothing
    call AddBuff(obj,obj,buffid,attribid,val,-1,false,0,duration,1,null)
  endfunction  
[/jass] |
|