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

一个球体效果叠加系统

[复制链接]
发表于 2009-1-2 17:29:18 | 显示全部楼层 |阅读模式
[jass]
function InitTrig_AttackDetect takes nothing returns nothing
endfunction
//##Start##
//***************************************************************************************************
//*
//*  AttackDetect: Flawed method for detecting attack hits
//*
//*     If you don't have this engine in your map yet, then copy the text from the
//*  //##Start## to the //##End## TO YOUR MAP's CUSTOM SCRIPT SECTION, (it is at the top of
//*  the trigger list in the trigger editor)
//*
//*  (If you have other stuff in the custom script section like the caster system just insert
//* this function below the contents of your custom script section)
//*
//*  (If you already have this function in your map don't copy this one)
//*
//***************************************************************************************************

//===================================================================================================
//
// For more JASS scripts, visit: http://www.wc3JASS.com
//
//###################################################################################################
//
// Configuration:
//
//================================================================================================
constant function AttackDetect_MinimumAttackCooldown takes nothing returns real
    return 0.2
endfunction

constant function AttackDetect_MaxFunctionsExecuted takes nothing returns integer
    return 3
endfunction

//###################################################################################################
//
// Private:
//
function AttackDetect_RunFuncs takes string k returns nothing
local integer n=GetTableInt(k,"#N")
local integer cp=AttackDetect_MaxFunctionsExecuted()
local integer i=1
local integer j
    if (n<=cp) then
        loop
            exitwhen (i>n)
            call ExecuteFunc(GetTableString(k,I2S(i)))
            set i=i+1
        endloop
    else
        set j=GetRandomInt(1,n)
        loop
            exitwhen (i>cp)
            if (j>n) then
                set j=1
            endif
            call ExecuteFunc(GetTableString(k,I2S(j)))
            set j=j+1
            set i=i+1
        endloop
    endif
endfunction


function AttackDetect_KillTrigger takes trigger t, string k returns nothing
    call SetTableObject(k,"#trigger",null)
    if (t!=null) then
        call TriggerRemoveAction(t,GetAttachedTriggerAction(t,"ac"))
        call CleanAttachedVars(t)
        call DestroyTrigger(t)
    endif
endfunction

function AttackDetect_OnDamage takes trigger t, unit a, string k returns nothing
local real ti
local real p
    if (a!=null) and (a==GetTableUnit(k,"#unit")) and (GetEventDamage()>=1) then
        call AttackDetect_KillTrigger(t,k)
        set ti=TimerGetElapsed(GetTableTimer("[AttackDetect]","Timer"))
        set p=GetTableReal(k,"#Last")
        if (ti-p>=AttackDetect_MinimumAttackCooldown() ) then
            call SetTableReal(k,"#Last",ti)
            call AttackDetect_RunFuncs(k)
        endif
    endif
endfunction

function AttackDetect_Sub takes nothing returns nothing
local trigger t=GetTriggeringTrigger()
local string k=GetAttachedString(t,"k")
    if (k=="") or (k==null) then
    elseif (GetTriggerEventId()==EVENT_UNIT_DAMAGED) then
        call AttackDetect_OnDamage(t,GetEventDamageSource(),k)
    else
        call AttackDetect_KillTrigger(t,k)
    endif
set t=null
endfunction

function AttackDetect_OnAttackStart takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit a=GetAttacker()
local trigger t
local string k
    if (a!=null) then
        set k=GetAttachmentTable(a)
        if HaveSetField(k,"AttackDetect_Table",bj_GAMECACHE_STRING) then
            set k=GetTableString(k,"AttackDetect_Table")
            if (GetTableInt(k,"#N")>0) then
                set t=GetTableTrigger(k,"#trigger")
                if (GetTableUnit(k,"#target")!=u) then
                    if (t!=null) then
                        call TriggerRemoveAction(t,GetAttachedTriggerAction(t,"ac"))
                        call CleanAttachedVars(t)
                        call DestroyTrigger(t)
                        set t=null
                    endif
                    call SetTableObject(k,"#target",u)
                elseif (t!=null) then
                    call EnableTrigger(t)
                endif
                if (t==null) then
                    set t=CreateTrigger()
                    call SetTableObject(k,"#trigger",t)
                    call AttachObject(t,"ac",TriggerAddAction(t,function AttackDetect_Sub))
                    call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_DAMAGED)
                    call TriggerRegisterUnitEvent(t,a,EVENT_UNIT_DEATH)
                    call AttachString(t,"k",k)
                endif
            endif
        endif
       set t=null
    endif
set u=null
set a=null
endfunction

//###################################################################################################
//
// Public:
//
//===================================================================================================
// Adds a function name to be executed whenever the unit makes a hit. (in theory)
//
function AttackDetect_AddFunc takes unit a, string funcname returns nothing
local integer n
local string k
local string ki=GetAttachmentTable(a)
    if HaveSetField(ki,"AttackDetect_Table",bj_GAMECACHE_STRING) then
        set k=GetTableString(ki,"AttackDetect_Table")
    else
        set k=NewTable()
        call SetTableString(ki,"AttackDetect_Table",k)
        call SetTableObject(k,"#unit",a)
    endif
    if (GetTableInt(k,funcname)==0) then
        set n=GetTableInt(k,"#N")+1
        call SetTableInt(k,funcname,n)
        call SetTableString(k,I2S(n),funcname)
        call SetTableInt(k,"#N",n)
    endif

endfunction

//===================================================================================================
// Removes the function name that was executed whenever the unit makes a hit
//
function AttackDetect_RemFunc takes unit a, string funcname returns nothing
local string ki=GetAttachmentTable(a)
local string k
local integer p
local integer n

    if HaveSetField(ki,"AttackDetect_Table",bj_GAMECACHE_STRING) then
        set k=GetTableString(ki,"AttackDetect_Table")
        set p=GetTableInt(k,funcname)
        if (p!=0) then
            set n=GetTableInt(k,"#N")
            if (n<=1) then
                //So, it only had that function, clean everything
                call SetTableString(ki,"AttackDetect_Table","")
                call DestroyTable(k)
            else
                call SetTableInt(k,funcname,0)
                if (p<n) then
                    set ki=GetTableString(k,I2S(n))
                    call SetTableString(k,I2S(p),ki)
                    call SetTableInt(k,ki,p)
                endif
                call SetTableString(k,I2S(n),"")
                call SetTableInt(k,"#N",n-1)
            endif
        endif
    endif
endfunction

//===================================================================================================
// Public because it is supposed to be helpful, returns the elapsed time since the game began
//
function AttackDetect_GetElapsed takes nothing returns real
    return TimerGetElapsed(GetTableTimer("[AttackDetect]","Timer"))
endfunction

//===================================================================================================
// Cleans pending triggers and the table before removing an unit
//
function AttackDetect_Clean takes unit a returns nothing
local string ki=GetAttachmentTable(a)
local string k
    if HaveSetField(ki,"AttackDetect_Table",bj_GAMECACHE_STRING) then
        set k=GetTableString(ki,"AttackDetect_Table")
        call AttackDetect_KillTrigger(GetTableTrigger(k,"#trigger"),k)
        call SetTableString(ki,"AttackDetect_Table","")
        call DestroyTable(k)
    endif
endfunction

//===================================================================================================
// Initializes the AttackDetect engine
//
function AttackDetect_Initialize takes nothing returns nothing
local trigger t=CreateTrigger()
local timer c=CreateTimer()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction(t, function AttackDetect_OnAttackStart )
    call TimerStart(c,5000,false,null)
    call SetTableObject("[AttackDetect]","Timer",c)
set c=null
set t=null
endfunction
//##End##
[/jass]
 楼主| 发表于 2009-1-3 11:02:44 | 显示全部楼层
例子1
[jass]
//********************************************************************************************************
//*                            A JESP Item ability by Vexorian
//* Codename: OrbOfManasteal
//* ˉˉˉˉˉˉˉˉ
//* Requirements:
//* ˉˉˉˉˉˉˉˉˉˉˉˉˉ
//* - The OrbOfManasteal item.
//* - The Caster System ( http://vexorian.wc3campaigns.net/ )
//* - This Trigger (Make sure to change the Item's rawcode to the correct one)
//*
//* Notes:
//* ˉˉˉˉˉˉ
//* - The Orbs stack and the number of orbs is represented by n on the config section.
//*
//********************************************************************************************************

//================================================================================================
// OrbOfManasteal Configuration:
//
////
// Essential
// ˉˉˉˉˉˉˉˉˉ
constant function OrbOfManasteal_ItemId takes nothing returns integer
//** Rawcode of the OrbOfManasteal item:
    return 'I000'
endfunction

////
// Balance:
// ˉˉˉˉˉˉˉˉ
constant function OrbOfManasteal_Chance takes integer n returns integer
//** Percentage Chance to drain mana:
    return 4+n
endfunction
constant function OrbOfManasteal_StolenMana takes real n returns real
//** Maximum mana points stolen:
    return 44+6*n
endfunction
constant function OrbOfManasteal_Cooldown takes real n returns real
//** Cooldown of the mana drain:
    return 10.5-0.5*n
endfunction

////
// Eye Candy:
// ˉˉˉˉˉˉˉˉˉˉ
constant function OrbOfManasteal_CasterArt takes nothing returns integer
//** A buff whose Target art is used by the orb as caster effect
    return 'Bdcm'
endfunction
constant function OrbOfManasteal_TargetArt takes nothing returns integer
//** A buff whose Target art is used by the orb as target effect
    return 'Bdtm'
endfunction
constant function OrbOfManasteal_Attach takes nothing returns string
//** Attachment point for both effects
    return "chest"
endfunction
constant function OrbOfManasteal_EffectDur takes nothing returns real
//** Duration of both effects
    return 1.5
endfunction




//========================================================================================================
// OrbOfManasteal code:
//
function OrbOfManasteal_Steal takes unit a, unit u, real x, string k returns nothing
local integer n=GetTableInt(k,"OrbOfManasteal_N")
local real ti=AttackDetect_GetElapsed()
local effect fx1
local effect fx2
local real p=GetTableReal(k,"OrbOfManasteal_Previous")
    if (p==0) or (ti-p>=OrbOfManasteal_Cooldown(n)) then
        if (GetRandomInt(1,100)<=OrbOfManasteal_Chance(n)) then
            call SetTableReal(k,"OrbOfManasteal_Previous",ti)
            set x=RMinBJ(OrbOfManasteal_StolenMana(n),x)
            call SetUnitState(a,UNIT_STATE_MANA, GetUnitState(a,UNIT_STATE_MANA)+x)
            call SetUnitState(u,UNIT_STATE_MANA, GetUnitState(u,UNIT_STATE_MANA)-x)

            set fx1=AddSpellEffectTargetById(OrbOfManasteal_CasterArt(),EFFECT_TYPE_TARGET,a,OrbOfManasteal_Attach())
            set fx2=AddSpellEffectTargetById(OrbOfManasteal_TargetArt(),EFFECT_TYPE_TARGET,u,OrbOfManasteal_Attach())
            call PolledWait(OrbOfManasteal_EffectDur())
            call DestroyEffect(fx1)
            call DestroyEffect(fx2)
        endif
    endif
set fx1=null
set fx2=null
endfunction

function OrbOfManasteal takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit a=GetEventDamageSource()
local real x=GetUnitState(u,UNIT_STATE_MANA)

    if (x>0) then
        call OrbOfManasteal_Steal(a,u,x,GetAttachmentTable(a))
    endif
set u=null
set a=null
endfunction

function OrbOfManasteal_Update takes unit u, integer c returns nothing
local string k=GetAttachmentTable(u)
local integer n=GetTableInt(k,"OrbOfManasteal_N")
    if (n==0) and (c>0) then
        call AttackDetect_AddFunc(u,"OrbOfManasteal")
    endif
    set n=n+c
    if (n==0) then
        call AttackDetect_RemFunc(u,"OrbOfManasteal")
    endif
    call SetTableInt(k,"OrbOfManasteal_N",n)
endfunction

function OrbOfManasteal_Cond takes nothing returns boolean
    return (GetItemTypeId(GetManipulatedItem())==OrbOfManasteal_ItemId())
endfunction

function OrbOfManasteal_GetLose takes nothing returns nothing
local unit u=GetTriggerUnit()
local string k=GetAttachmentTable(u)
local integer n=GetTableInt(k,"OrbOfManasteal_N")
    if (GetTriggerEventId()==EVENT_PLAYER_UNIT_PICKUP_ITEM) then
        if (n==0) then
            call AttackDetect_AddFunc(u,"OrbOfManasteal")
        endif
        call SetTableInt(k,"OrbOfManasteal_N",n+1)
    else
        call SetTableInt(k,"OrbOfManasteal_N",n-1)
        if (n<=1) then
            call AttackDetect_RemFunc(u,"OrbOfManasteal")
        endif
    endif
set u=null
endfunction

//================================================================================================
function InitTrig_OrbOfManasteal takes nothing returns nothing
    set gg_trg_OrbOfManasteal=CreateTrigger()
    call TriggerAddCondition(gg_trg_OrbOfManasteal,Condition(function OrbOfManasteal_Cond))
    call TriggerAddAction(gg_trg_OrbOfManasteal,function OrbOfManasteal_GetLose)
    call TriggerRegisterAnyUnitEventBJ(gg_trg_OrbOfManasteal,EVENT_PLAYER_UNIT_PICKUP_ITEM)
    call TriggerRegisterAnyUnitEventBJ(gg_trg_OrbOfManasteal,EVENT_PLAYER_UNIT_DROP_ITEM)
endfunction

[/jass]
回复

使用道具 举报

 楼主| 发表于 2009-1-3 11:05:00 | 显示全部楼层
[jass]
//********************************************************************************************************
//*                              A JESP InvXItem custom bonus by Vexorian
//* Codename: OrbOfSoulBurn
//* ˉˉˉˉˉˉˉˉ
//* Requirements:
//* ˉˉˉˉˉˉˉˉˉˉˉˉˉ
//* - The OrbOfSoulBurn Item
//* - The Caster System ( http://vexorian.wc3campaigns.net/ )
//* - An ability to cast
//* - This trigger (make sure it points to the right ability and item rawcodes)
//*
//* Notes:
//* ˉˉˉˉˉˉ
//* - Each extra OrbOfSoulBurn item increases the n value used on config section.
//* - The level of the ability tries to match the current n value or the ability's maximum level
//*   (whichever is higher)
//*
//********************************************************************************************************

//================================================================================================
// OrbOfSoulBurn Configuration:
//
////
// Essential
// ˉˉˉˉˉˉˉˉˉ
constant function OrbOfSoulBurn_ItemId takes nothing returns integer
//** Rawcode of the OrbOfSoulBurn item:
    return 'I001'
endfunction

////
// Orb Options:
// ˉˉˉˉˉˉˉˉˉˉˉˉ
constant function OrbOfSoulBurn_Chance takes integer n returns integer
//** Percentage chance of the orb:
    return 23+2*n
endfunction
constant function OrbOfSoulBurn_Cooldown takes real n returns real
//** The orb's cooldown
    return 5.1-n*0.1
endfunction

////
// Spell To Cast Options:
// ˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉ
constant function OrbOfSoulBurn_ToCastSpellId takes nothing returns integer
//** Rawcode of the Spell to cast:
    return 'A001'
endfunction
constant function OrbOfSoulBurn_ToCastOrderId takes nothing returns integer
//** OrderId of the spell to cast:
    return OrderId("soulburn")
endfunction
constant function OrbOfSoulBurn_RecycleDelay takes real n returns real
//** Recycle delay for the spell to cast, The duration of the damage done by it
    return 15+0*n
endfunction





//========================================================================================================
// OrbOfSoulBurn code:
// ˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉ
function OrbOfSoulBurn_Magic takes unit a, unit u returns nothing
local string k=GetAttachmentTable(a)
local integer n=GetTableInt(k,"OrbOfSoulBurn_N")
local real ti=AttackDetect_GetElapsed()
local real p=GetTableReal(k,"OrbOfSoulBurn_Previous")
    if (p==0) or (ti-p>=OrbOfSoulBurn_Cooldown(n)) then
        if (GetRandomInt(1,100)<=OrbOfSoulBurn_Chance(n)) then
            call SetTableReal(k,"OrbOfSoulBurn_Previous",ti)
            call CasterCastAbilityEx(GetOwningPlayer(a),GetUnitX(a),GetUnitY(a),GetUnitFlyHeight(a),OrbOfSoulBurn_ToCastSpellId(),n,I2S(OrbOfSoulBurn_ToCastOrderId()),u,OrbOfSoulBurn_RecycleDelay(n))
        endif
    endif
endfunction

function OrbOfSoulBurn_Update takes unit u, integer c returns nothing
local string k=GetAttachmentTable(u)
local integer n=GetTableInt(k,"OrbOfSoulBurn_N")
    if (n==0) and (c>0) then
        call AttackDetect_AddFunc(u,"OrbOfSoulBurn")
    endif
    set n=n+c
    if (n==0) then
        call AttackDetect_RemFunc(u,"OrbOfSoulBurn")
    endif
    call SetTableInt(k,"OrbOfSoulBurn",n)
endfunction

function OrbOfSoulBurn takes nothing returns nothing
    call OrbOfSoulBurn_Magic(GetEventDamageSource(),GetTriggerUnit())
endfunction


function OrbOfSoulBurn_Cond takes nothing returns boolean
    return (GetItemTypeId(GetManipulatedItem())==OrbOfSoulBurn_ItemId())
endfunction

function OrbOfSoulBurn_GetLose takes nothing returns nothing
local unit u=GetTriggerUnit()
local string k=GetAttachmentTable(u)
local integer n=GetTableInt(k,"OrbOfSoulBurn_N")
    if (GetTriggerEventId()==EVENT_PLAYER_UNIT_PICKUP_ITEM) then
        if (n==0) then
            call AttackDetect_AddFunc(u,"OrbOfSoulBurn")
        endif
        call SetTableInt(k,"OrbOfSoulBurn_N",n+1)
    else
        call SetTableInt(k,"OrbOfSoulBurn_N",n-1)
        if (n<=1) then
            call AttackDetect_RemFunc(u,"OrbOfSoulBurn_N")
        endif
    endif
set u=null
endfunction

//================================================================================================
function InitTrig_OrbOfSoulBurn takes nothing returns nothing
    set gg_trg_OrbOfSoulBurn=CreateTrigger()
    call TriggerAddCondition(gg_trg_OrbOfSoulBurn,Condition(function OrbOfSoulBurn_Cond))
    call TriggerAddAction(gg_trg_OrbOfSoulBurn,function OrbOfSoulBurn_GetLose)
    call TriggerRegisterAnyUnitEventBJ(gg_trg_OrbOfSoulBurn,EVENT_PLAYER_UNIT_PICKUP_ITEM)
    call TriggerRegisterAnyUnitEventBJ(gg_trg_OrbOfSoulBurn,EVENT_PLAYER_UNIT_DROP_ITEM)
    call PreloadAbility(OrbOfSoulBurn_ToCastSpellId())
endfunction

[/jass]
回复

使用道具 举报

 楼主| 发表于 2009-1-3 11:08:16 | 显示全部楼层
第三个例子
[jass]
//********************************************************************************************************
//*                              A JESP InvXItem custom bonus by Vexorian
//* Codename: OrbOfFire
//* ˉˉˉˉˉˉˉˉ
//* Requirements:
//* ˉˉˉˉˉˉˉˉˉˉˉˉˉ
//* - The OrbOfFire Item
//* - The Caster System ( http://vexorian.wc3campaigns.net/ )
//* - This Trigger (Make sure it points to the right Item rawcode)
//*
//* Notes
//* ˉˉˉˉˉ
//* - Each extra OrbOfFire item increases the n value used on config section.
//*
//********************************************************************************************************

//================================================================================================
// OrbOfFire Configuration:
//
////
// Essential
// ˉˉˉˉˉˉˉˉˉ
constant function OrbOfFire_ItemId takes nothing returns integer
//** Rawcode of the OrbOfFire item:
    return 'I001'
endfunction

////
// Balance
// ˉˉˉˉˉˉˉ
constant function OrbOfFire_Chance takes integer n returns integer
//** Percentage chance of the orb:
    return 100+0*n
endfunction
constant function OrbOfFire_Cooldown takes real n returns real
//** Cooldown of the orb:
    return 0-0*n
endfunction
constant function OrbOfFire_Area takes real n returns real
//** Area of effect of the damage:
    return 140+10*n // The area of effect of the damage
endfunction
constant function OrbOfFire_DamageFactor takes real n returns real
//** The damage factor for the damage, Original damage multiplied by this value is
//   the damage used for the AOE damage:
    return 0.4+0.1*n
endfunction
function OrbOfFire_DamageOptions takes integer n returns integer
//** Damage options:
    return DamageTypes(ATTACK_TYPE_NORMAL,DAMAGE_TYPE_FIRE)+DamageOnlyEnemies()
//
// Will do normal fire (magical) damage only to enemies, more damage options can be used,
// Check the caster system's readme for more information
//
endfunction

////
// Eye candy:
// ˉˉˉˉˉˉˉˉˉˉ
constant function OrbOfFire_TargetArt takes nothing returns integer
//** The special art of this ability is used as target effect of the orb
    return 'AIfb'
endfunction
constant function OrbOfFire_TargetAttach takes nothing returns string
//** The attachment point for that effect
    return "chest"
endfunction





//========================================================================================================
// OrbOfFire code:
//
function OrbOfFire_Magic takes unit a, unit u returns nothing
local string k=GetAttachmentTable(a)
local integer n=GetTableInt(k,"OrbOfFire_N")
local real ti=AttackDetect_GetElapsed()
local real p=GetTableReal(k,"OrbOfFire_Previous")
    if (p==0) or (ti-p>=OrbOfFire_Cooldown(n)) then
        if (GetRandomInt(1,100)<=OrbOfFire_Chance(n)) then
            call SetTableReal(k,"OrbOfFire_Previous",ti)
            call DestroyEffect(AddSpellEffectTargetById(OrbOfFire_TargetArt(),EFFECT_TYPE_SPECIAL,u,OrbOfFire_TargetAttach()))
            call DamageUnitsInAOEEx(a,GetEventDamage()*OrbOfFire_DamageFactor(n),GetUnitX(u),GetUnitY(u),OrbOfFire_Area(n),false,OrbOfFire_DamageOptions(n))
        endif
    endif
endfunction

function OrbOfFire takes nothing returns nothing
    call OrbOfFire_Magic(GetEventDamageSource(),GetTriggerUnit())
endfunction

function OrbOfFire_Cond takes nothing returns boolean
    return (GetItemTypeId(GetManipulatedItem())==OrbOfFire_ItemId())
endfunction

function OrbOfFire_GetLose takes nothing returns nothing
local unit u=GetTriggerUnit()
local string k=GetAttachmentTable(u)
local integer n=GetTableInt(k,"OrbOfFire_N")
    if (GetTriggerEventId()==EVENT_PLAYER_UNIT_PICKUP_ITEM) then
        if (n==0) then
            call AttackDetect_AddFunc(u,"OrbOfFire")
        endif
        call SetTableInt(k,"OrbOfFire_N",n+1)
    else
        call SetTableInt(k,"OrbOfFire_N",n-1)
        if (n<=1) then
            call AttackDetect_RemFunc(u,"OrbOfFire")
        endif
    endif
set u=null
endfunction

//================================================================================================
function InitTrig_OrbOfFire takes nothing returns nothing
    set gg_trg_OrbOfFire=CreateTrigger()
    call TriggerAddCondition(gg_trg_OrbOfFire,Condition(function OrbOfFire_Cond))
    call TriggerAddAction(gg_trg_OrbOfFire,function OrbOfFire_GetLose)
    call TriggerRegisterAnyUnitEventBJ(gg_trg_OrbOfFire,EVENT_PLAYER_UNIT_PICKUP_ITEM)
    call TriggerRegisterAnyUnitEventBJ(gg_trg_OrbOfFire,EVENT_PLAYER_UNIT_DROP_ITEM)
endfunction
[/jass]
回复

使用道具 举报

发表于 2009-1-3 12:57:37 | 显示全部楼层
  很好,除了没看明白意外其他的都不错
回复

使用道具 举报

 楼主| 发表于 2009-1-8 12:54:38 | 显示全部楼层
魔兽地图吧高人写的一个伤害显示系统
[jass]
//***************************************************************************
//* Damage Show System Functions                                            *
//* Edit by feelerly                                                        *
//* 2008.02.20                                                              *
//* Welcome to visit us and discuss with in http://bbs.wow8.org             *
//***************************************************************************
// 这些功能是支持伤害显示系统的一些其他函数,可以删除.但为了完整,建议保留这些函数.
// 本套函数基于前一次发布的显示系统, 现在已经完美了,设置附加伤害方面也人性化了.
// ---->> 最完美的伤害显示系统,无泄漏,绿色环保,随心所欲设置伤害!
// ---->> 为什么是完美的呢?因为可以实现单位受伤害时,任意加成或减少伤害,由于引入了"伤害加成因素"这个概念
// 使得加成伤害变量随心所欲,便于控制.那什么是伤害加成因素呢?就是伤害来源所拥有的一个条件,现在只
// 添加了单位,物品,单位组,玩家,玩家组,地区,区域六个因素,也就是说,伤害来源拥有以上六个因素之一,就可以对
// 目标单位造成伤害加成,反之则不加成.如果开启伤害显示时,没有设置伤害加成因素,那么会默认为受到任何
// 伤害都会对目标进行伤害加成触发.加成伤害有两种运算方式: 加法运算和乘法运算.0为加法,1为乘法.将负
// 数带入运算会加成伤害的值小于0,这时会自动调整为目标减少伤害,当然,这个也要因素满足条件才行.
// 目前,这个系统应该是最完美的伤害显示系统了,经过偶的排泄处理,在地图中对于游戏不会有什么影响.而且
// 还可以随意添加和修改脚本中的一些数据以达到想要的各种伤害效果.
// 建议: 使用ReturnBugSystem数据转换函数做为支撑函数,这套系统需要ReturnBugSystem数据转换函数的支持
//===========================================================================
// 数据转换系统功能函数
//===========================================================================
// ==========>> 数据转换系统 <<==========
function CacheValue takes nothing returns gamecache
    // CacheValue 缓存函数,这个函数是用来设置储存的缓存文件的.一般不需要更改
    // 如果你想使用自定义函数,可以用bj_lastCreatedGameCache来设定缓存.系统会自
    // 动识别的(要在初始化地图时就设置,不然会出错的.)
    if bj_lastCreatedGameCache == null then
        call FlushGameCache( bj_lastCreatedGameCache )
        set bj_lastCreatedGameCache = InitGameCache( "ReturnBugSystem.w3v")
    endif
    return bj_lastCreatedGameCache
endfunction
constant function ConvertHandleInt takes handle h returns integer
    return h // 将句柄值转换为整数值
    return 0 // return 0 实际是不会运行的,做为欺骗Jass语法检查用的
endfunction
constant function ConvertHandle takes integer i returns handle
    return i // 将整数值转换为句柄值.转换单位玩家之类的同理.
    return null
endfunction
constant function ConvertUnit takes integer i returns unit
    return i
    return null
endfunction
constant function ConvertItem takes integer i returns item
    return i
    return null
endfunction
constant function ConvertForce takes integer i returns force
    return i
    return null
endfunction
constant function ConvertGroup takes integer i returns group
    return i
    return null
endfunction
constant function ConvertPlayer takes integer i returns player
    return i
    return null
endfunction
constant function ConvertRect takes integer i returns rect
    return i
    return null
endfunction
constant function ConvertRegion takes integer i returns region
    return i
    return null
endfunction
constant function ConvertTrigger takes integer i returns trigger
    return i
    return null
endfunction
constant function ConvertAction takes integer i returns triggeraction
    return i
    return null
endfunction
function HandleName takes handle h returns string
    return I2S( ConvertHandleInt( h ) )
endfunction
function Debug takes string s returns nothing
    local integer a = 0
    loop
        call DisplayTimedTextToPlayer( Player(a), 0, 0, 60.00, s )
        set a = a + 1
        exitwhen a == 11
    endloop
    set a = 0
endfunction
//===========================================================================
// Convert Data end
//===========================================================================
function RandomColor takes string s returns string
// 随机文字颜色处理,创造多彩文字,让游戏显得更有个性!
    local string hex = "0123456789abcdef"
    local string color = null
    local string id = null
    local integer a = 0
    local integer b = 0
    loop
        set b = GetRandomInt(1,16)
        set id = SubString( hex, b - 1, b )
        set color = color + id
        set a = a + 1
        exitwhen a == 6
    endloop
    set id = null
    return "|cff" + color + s + "|r"
endfunction
// ---->判断handle值的类型!有的时候可以起来防止数据混乱的情况.
// !完美无泄漏. 一般判断handle的用户类型是没有必要的,但可以做为判断一些数据的依据.
// 这个也是以上所以伤害加成因素判断的函数,因些不能删除.
function IsHandleUnit takes integer i returns boolean
    local unit u = ConvertUnit( i )
    local boolean b = false
    if GetUnitState( u, UNIT_STATE_LIFE ) > 0.00 then
        set b = true
    endif
    set u = null
    return b
endfunction
function IsHandleItem takes integer i returns boolean
    local item it = ConvertItem( i )
    local integer ud = GetItemUserData( it )
    local boolean b = false
    call SetItemUserData( it, ud + 1 )
    if GetItemUserData( it ) > 0 then
        set b = true
    endif
    call SetItemUserData( it, ud )
    set it = null
    return b
endfunction
function IsHandleGroup takes integer i returns boolean
    local group g = ConvertGroup( i )
    local unit u = CreateUnit( Player(12), 'ewsp', 0, 0, 0 )
    local boolean b = false
    call GroupAddUnit( g, u )
    if IsUnitInGroup( u, g ) == true then
        set b = true
    endif
    call GroupRemoveUnit( g, u )
    call RemoveUnit( u )
    set g = null
    set u = null
    return b
endfunction
function IsHandlePlayer takes integer i returns boolean
    local player p = ConvertPlayer( i )
    local boolean b = false
    if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
        set b = true
    endif
    set p = null
    return b
endfunction
function IsHandleForce takes integer i returns boolean
    local force f = ConvertForce( i )
    local boolean b = false
    if IsPlayerInForce( Player(12), f ) == false then
        call ForceAddPlayer( f, Player(12) )
    endif
    if IsPlayerInForce( Player(12), f ) == true then
        set b = true
    endif
    set f = null
    return b
endfunction
function IsHandleRect takes integer i returns boolean
    local rect r = ConvertRect( i )
    local real rx = GetRandomReal( GetRectMinX(r), GetRectMaxX(r) )
    local real ry = GetRandomReal( GetRectMinY(r), GetRectMaxY(r) )
    local boolean b = false
    if rx != 0.00 and ry != 0.00 then
        if GetRectMinX(r) < rx and GetRectMaxX(r) > rx and GetRectMinY(r) < ry and GetRectMaxY(r) > ry then
            set b = true
        endif
    endif
    set r = null
    return b
endfunction
function IsHandleRegion takes integer i returns boolean
    local region r = ConvertRegion( i )
    local boolean b = false
    call RegionAddCell( r, 0, 0 )
    if IsPointInRegion( r, 0, 0) then
        set b = true
    endif
    set r = null
    return b
endfunction
// ----> 判断伤害来源是否满足伤害目标所提供的伤害加成因素,如果满足则进行伤害加成.
function AddSourceIsExist takes unit u, unit s returns boolean
// 检查附加伤害因素是否存在, 目前可以支持单位,物品,单位组,玩家,势力,地区,区域
// 单位就是伤害源为指定的单位, 单位组是指伤害源在指定单位组中, 玩家是指伤害源属于某个指定玩家
// 而势力是指伤害源所属玩家组, 地区是指伤害源在某个地区内, 区域与地区的效果相同.
// 物品是指伤害来源是否拥有这个物品.
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local integer h = 0
    local boolean b = false
    local string name = I2S( ConvertHandleInt(u) )
    if HaveStoredInteger(CacheValue(), name, "NoSource") then
        set b = true
    elseif HaveStoredInteger(CacheValue(), name, "AddUnitSource" ) then
         set b = true
    elseif HaveStoredInteger(CacheValue(), name, "AddItemSource" ) then
         if UnitHasItem( s, ConvertItem(GetStoredInteger(CacheValue(), name, "AddItemSource" )) ) then
             set b = true
         endif
    elseif HaveStoredInteger(CacheValue(), name, "AddGroupSource" ) then
        if IsUnitInGroup( s, ConvertGroup(GetStoredInteger(CacheValue(), name, "AddGroupSource" )) ) then
            set b = true
        endif
    elseif HaveStoredInteger(CacheValue(), name, "AddPlayerSource" ) then
        if GetOwningPlayer( s ) == ConvertPlayer(GetStoredInteger(CacheValue(), name, "AddPlayerSource" )) then
            set b = true
        endif
    elseif HaveStoredInteger(CacheValue(), name, "AddForceSource" ) then
        if IsPlayerInForce( GetOwningPlayer( s ), ConvertForce(GetStoredInteger(CacheValue(), name, "AddForceSource" ))) then
            set b = true
        endif
    elseif HaveStoredInteger(CacheValue(), name, "AddRectSource" ) then
        set h = GetStoredInteger(CacheValue(), name, "AddRectSource" )
        if RectContainsCoords( ConvertRect(h), x, y ) then
            set b = true
        endif
    elseif HaveStoredInteger(CacheValue(), name, "AddRegionSource" ) then
        set h = GetStoredInteger(CacheValue(), name, "AddRegionSource" )
        if IsPointInRegion( ConvertRegion(h), x, y ) then
            set b = true
        endif
    endif
    return b
endfunction
// - -||| 一个附加效果, 可以改变伤害来源的生命值, 做为测试来用, 建议在添加时禁用这个功能.
function AddLifeValueOfSource takes real life returns nothing
// 改变伤害来源生命,以实现传说中的"吸血伤害"或者"反弹伤害"效果.
    local effect e = null
    if life > 0.00 and GetUnitState( GetEventDamageSource() ,UNIT_STATE_LIFE ) > 0.00 and GetTriggerUnit() != GetEventDamageSource() then
        if GetUnitState( GetEventDamageSource() ,UNIT_STATE_LIFE ) - life <= 0.00 then
            set life = GetUnitState( GetEventDamageSource() ,UNIT_STATE_LIFE ) - 2.00
        endif
        set e = AddSpecialEffectTarget("Abilities\\\\Spells\\\\Undead\\\\VampiricAura\\\\VampiricAuraTarget.mdl", GetEventDamageSource(), "origin")
    elseif life == 0.00 and GetUnitState( GetEventDamageSource() ,UNIT_STATE_LIFE ) > 0.00 and GetTriggerUnit() != GetEventDamageSource() then
        set e = AddSpecialEffectTarget("Abilities\\\\Spells\\\\Human\\\\Slow\\\\SlowCaster.mdl", GetEventDamageSource(), "origin")
    elseif life < 0.00 and GetUnitState( GetEventDamageSource() ,UNIT_STATE_LIFE ) > 0.00 and GetTriggerUnit() != GetEventDamageSource() then
        set e = AddSpecialEffectTarget("Abilities\\\\Weapons\\\\FlyingMachine\\\\FlyingMachineImpact.mdl", GetEventDamageSource(), "chest")
    endif
    call DestroyEffect( e )
    call SetUnitState( GetEventDamageSource(), UNIT_STATE_LIFE, GetUnitState( GetEventDamageSource() ,UNIT_STATE_LIFE ) + life )
    set e = null
endfunction
// - -||| END!
// ----> 单位受伤害时,显示所受的伤害值 <----
function ShowDamageForUnitActions takes nothing returns nothing
    local texttag tt = CreateTextTag()
    local unit u = GetTriggerUnit()
    local unit s = GetEventDamageSource()
    local integer mtd = GetStoredInteger( CacheValue(), I2S(ConvertHandleInt(u)), "AddMethod" )
    local real admg = GetStoredReal( CacheValue(), I2S(ConvertHandleInt(u)), "AddDamage" )
    local real dmg = GetEventDamage()
    local real life = 0.00
    local string text = null
    call Debug( "伤害计算: "+R2S(dmg) + " || " + R2S(admg) + " ? " + I2S(mtd))
    if dmg <= 0.00 then
        call DestroyTextTag( tt )
    else
        // 如果单位所受伤害大于单位当前生命,即单位被秒杀,则不进行伤害的加成判断.
        if dmg >= GetUnitState( u ,UNIT_STATE_LIFE ) then
            set dmg = GetUnitState( u ,UNIT_STATE_LIFE )
        else
            // ----> 实际所受伤害值
            set life = GetUnitState( u ,UNIT_STATE_LIFE )
            if AddSourceIsExist( u, s ) then
                if mtd == 0 then // 0 为加减运算
                // 根据运算方式, 来决定单位最终所受附加伤害.
                    set dmg = admg
                elseif mtd == 1 then // 1 为乘法运算
                    set dmg = dmg*admg - dmg
                    //if admg < 1 and admg >= 0.00 then
                    //     set dmg = dmg * admg// 乘法运算时, 0 - 1 之间的加成按照(事件伤害*加成伤害) 来计算
                    //endif
                endif
                call Debug( "伤害加成: " + R2S(GetEventDamage()) + " || " + R2S(dmg) )
                // ----> 修正所受伤害值, dmg 为负则减伤, 为正则加伤
                // 算法上可能有一些出入,但实际单位所伤害的应该是符合计算结果的.
                if dmg > 0.00 then
                    if GetUnitState( u ,UNIT_STATE_LIFE ) - dmg <= 0.00 then
                        call SetUnitState( u, UNIT_STATE_LIFE, 1.00 )
                    else
                        call SetUnitState( u, UNIT_STATE_LIFE, GetUnitState( u ,UNIT_STATE_LIFE ) - dmg )
                    endif
                elseif dmg < 0.00 then
                    if GetUnitState( u ,UNIT_STATE_LIFE ) - dmg >= life + GetEventDamage() then
                        call SetUnitState( u, UNIT_STATE_LIFE, life + GetEventDamage() )
                    else
                        call SetUnitState( u, UNIT_STATE_LIFE, GetUnitState( u ,UNIT_STATE_LIFE ) + (-dmg) )
                    endif
                endif
                set life = life - GetUnitState( u ,UNIT_STATE_LIFE )
                call Debug(  "所受加成: " + R2S(GetEventDamage()) + " || " + R2S(life) )
            endif
            set dmg = GetEventDamage() + life
            call Debug(  "最终伤害: " + R2S(GetEventDamage()) + " || " + R2S(life) )
// ----> 选择附加的效果,这些效果可以自己定义, 因此不在参数中设置了,可以用条件来设置是否执行附加的效果.
// ----> 如果没有条件限制, 则是直接执行附加效果.不过如果要加附加的效果,必须在这个位置以下添加.
    call AddLifeValueOfSource( (dmg * 0.50) ) // 改变伤害来源的生命值.带入负数则是减少生命.
// ----> 附加效果自己可以创建的, 比如反弹魔法, 或者是其他的触发.
            // ----> 所显示计算后的伤害值
            if dmg <= 0.04999 then
                set text = RandomColor("Miss!")
            else
                set text = RandomColor("-" + R2SW(dmg,-1,1) )
            endif
        endif
        // -> 以下是漂浮文字的设定,颜色是随机的,自己可以添加颜色.
        call SetTextTagText( tt, text, TextTagSize2Height(11) )
        call SetTextTagPos( tt, GetUnitX(u),GetUnitY(u), 16+GetUnitFlyHeight(u) )
        call SetTextTagColor( tt, 255, 255, 255, 157 )
        call SetTextTagVelocityBJ( tt, GetRandomReal(100,161.8), GetRandomReal(60,120) )
        call SetTextTagPermanent( tt, false )
        call SetTextTagLifespan( tt, 1.618 )
        call SetTextTagFadepoint( tt, 0.618 )
    endif
    set dmg = 0.00
    set tt = null
    set s = null
    set u = null
endfunction
function ResetAddSource takes unit u returns nothing
// 清理附加伤害因素, 在重新选定伤害因素时, 必须清空以前所注入的数据.
    local string name = I2S(ConvertHandleInt(u))
    call FlushStoredInteger( CacheValue(), name, "NoSource" )
    call FlushStoredInteger( CacheValue(), name, "AddUnitSource" )
    call FlushStoredInteger( CacheValue(), name, "AddItemSource" )
    call FlushStoredInteger( CacheValue(), name, "AddGroupSource" )
    call FlushStoredInteger( CacheValue(), name, "AddForceSource" )
    call FlushStoredInteger( CacheValue(), name, "AddPlayerSource" )
    call FlushStoredInteger( CacheValue(), name, "AddRectSource" )
    call FlushStoredInteger( CacheValue(), name, "AddRegionSource" )
endfunction
function ShowDamageForUnit takes unit u, boolean b, real admg, integer method, handle h returns nothing
// -> 如果 b 等于 true 时,则认为单位开启了伤害显示与伤害加成,b 为 false 时,则认为是关闭了伤害显示与伤害加成.
    local string name = I2S(ConvertHandleInt(u))
    local trigger trig = null
    local triggeraction ta = null
    local boolean flag = GetStoredBoolean( CacheValue(), I2S(ConvertHandleInt(u)), "HasShowedDamage" )
    if b == true then
        if flag == false and GetStoredInteger( CacheValue(), name, "UnitDamageTrigger" ) == 0 then
            set trig = CreateTrigger() // 如果单位没有开启过伤害显示, 则创建相关的触发, 开启单位的伤害显示.
            call TriggerRegisterUnitEvent( trig, u, EVENT_UNIT_DAMAGED )
            set ta = TriggerAddAction( trig, function ShowDamageForUnitActions )
            call StoreInteger( CacheValue(), name, "UnitDamageTrigger", ConvertHandleInt(trig) )
            call StoreInteger( CacheValue(), I2S(ConvertHandleInt(trig)), "TriggerAction", ConvertHandleInt(ta) )
        elseif flag == true then // 如果开启的伤害显示被关闭,则打开.
            set trig = ConvertTrigger( GetStoredInteger( CacheValue(), name, "UnitDamageTrigger" ) )
            if IsTriggerEnabled( trig ) == false then
                call EnableTrigger( trig )
            endif
        endif
        call ExecuteFunc( "TriggerCheckUnitDamageShow" ) // 运行触发检查单位是否死亡,如果死亡则清除相关伤害显示
        call ResetAddSource( u ) // 清空以前设置的附加伤害来源
        call StoreInteger( CacheValue(), name, "AddMethod", method ) // 附加伤害的计算方法
        call StoreReal( CacheValue(), name, "AddDamage", admg ) // 所附加的伤害
        // ----> 设置附加伤害因素,在单位受到伤害时,会检查所注入的数据.以此来判断一个单位接受的伤害加成.
        if ConvertHandleInt(h) <= 0 then // 如果没有设置因素,则默认为因素不存在,所有对该单位造成的伤害都会进行加成.
            call StoreInteger( CacheValue(), name, "NoSource", ConvertHandleInt(h) )
        elseif IsHandleUnit(ConvertHandleInt(h)) then // 设置单位因素,只有这个指定单位对该单位伤害时具有伤害加成效果
            call StoreInteger( CacheValue(), name, "AddUnitSource", ConvertHandleInt(h) )
        elseif IsHandleItem(ConvertHandleInt(h)) then // 设置物品因素,只有持有指定物品的单位对该单位伤害时具有伤害加成效果
            call StoreInteger( CacheValue(), name, "AddItemSource", ConvertHandleInt(h) )
        elseif IsHandleGroup(ConvertHandleInt(h)) then // 设置单位组因素, 只有这个单位组中的单位对该单位造成伤害时有加成效果
            call StoreInteger( CacheValue(), name, "AddGroupSource", ConvertHandleInt(h) )
        elseif IsHandlePlayer(ConvertHandleInt(h)) then // 设置玩家因素
            call StoreInteger( CacheValue(), name, "AddPlayerSource", ConvertHandleInt(h) )
        elseif IsHandleForce(ConvertHandleInt(h)) then // 设置玩家组(势力)因素
            call StoreInteger( CacheValue(), name, "AddForceSource", ConvertHandleInt(h) )
        elseif IsHandleRect( ConvertHandleInt(h) ) then // 设置地区因素
            call StoreInteger( CacheValue(), name, "AddRectSource", ConvertHandleInt(h) )
        elseif IsHandleRegion( ConvertHandleInt(h) ) then // 设置区域因素
            call StoreInteger( CacheValue(), name, "AddRetionSource", ConvertHandleInt(h) )
        endif
    elseif flag == true then
        set trig = ConvertTrigger( GetStoredInteger( CacheValue(), name, "UnitDamageTrigger" ) )
        call DisableTrigger( trig )
    endif
    call StoreBoolean( CacheValue(), I2S(ConvertHandleInt(u)), "HasShowedDamage", b )
    set trig = null
    set ta = null
endfunction
// ----> END <----
// ----> 触发检查单位伤害显示状态 <----
function TriggerCheckUnitDamageShowActions takes nothing returns nothing
// 触发检查单位伤害显示状态,如果单位死亡则清除单位的伤害显示.
    local string name = I2S(ConvertHandleInt(GetTriggerUnit()))
    local trigger trig = null
    local triggeraction ta = null
    if GetStoredBoolean( CacheValue(), name, "HasShowedDamage" ) == true then
        call FlushStoredBoolean( CacheValue(), name, "HasShowedDamage" )
        call ResetAddSource( GetTriggerUnit() )
        set trig = ConvertTrigger( GetStoredInteger( CacheValue(), name, "UnitDamageTrigger" ) )
        set ta = ConvertAction( GetStoredInteger( CacheValue(), I2S(ConvertHandleInt(trig)), "TriggerAction" ) )
        call FlushStoredInteger( CacheValue(), name, "UnitDamageTrigger" )
        call FlushStoredReal( CacheValue(), name, "AddDamage" )
        call TriggerRemoveAction( trig, ta )
        call FlushStoredMission( CacheValue(), I2S(ConvertHandleInt(trig)) )
        call DestroyTrigger( trig )
    endif
    set trig = null
    set ta = null
endfunction
function TriggerCheckUnitDamageShow takes nothing returns nothing
// 触发检查单位伤害显示的设置状态,如果单位死亡,则清除单位的伤害显示内容,包括英雄在内.
// ----> 这个检查针对所有玩家的包括中立的玩家.这个不能被关闭,一旦关闭了,很可能造成数据泄漏.
    local boolexpr f = null
    local trigger trig = null
    local triggeraction ta = null
    local integer i = 0
    if GetStoredBoolean( CacheValue(), "Maps", "CheckDamageEnable" ) == false then
        set trig = CreateTrigger()
        loop
            call TriggerRegisterPlayerUnitEvent( trig, Player(i), EVENT_PLAYER_UNIT_DEATH, f )
            set i = i + 1
            exitwhen i == 14
        endloop
        set ta = TriggerAddAction( trig, function TriggerCheckUnitDamageShowActions )
        call StoreInteger( CacheValue(), "Maps", "DamageShowCheck", ConvertHandleInt(trig) )
        call StoreInteger( CacheValue(), I2S(ConvertHandleInt(trig)), "TriggerAction", ConvertHandleInt(ta) )
        call StoreBoolean( CacheValue(), "Maps", "CheckDamageEnable", true )
    endif
    call DestroyBoolExpr( f )
    set trig = null
    set ta = null
    set f = null
endfunction
// ----> END <----
// ----> 计时检查地图上所有单位伤害显示状态 <----
function ShowDamageForPlayerUnitActionsFunc takes unit u returns nothing
    local string pname = I2S(ConvertHandleInt(GetOwningPlayer(u)))
    local string uname = I2S(ConvertHandleInt(u))
    local integer method = GetStoredInteger( CacheValue(), pname, "AddMethod" )
    local integer source = GetStoredInteger( CacheValue(), pname, "AddSource" )
    local real admg = GetStoredReal( CacheValue(), pname, "AddDamage" )
    if GetStoredBoolean( CacheValue(), pname, "HasShowedDamage" ) == true then
        if GetStoredBoolean( CacheValue(), uname, "HasShowedDamage" ) == false then
            call ShowDamageForUnit( u, true, admg, method, ConvertHandle(source) )
        endif
    endif
    set source = 0
    set pname = null
    set uname = null
    set u = null
endfunction
function ShowDamageForPlayerUnitGroupActions takes nothing returns nothing
// 检查单位受到攻击或者计时器到期时运行这个函数,以便于自动给单位添加伤害显示.
    if GetStoredBoolean( CacheValue(), I2S(ConvertHandleInt(GetEnumUnit())), "HasShowedDamage" ) == false then
        call ShowDamageForPlayerUnitActionsFunc( GetEnumUnit() )
    endif
endfunction
function ShowDamageForPlayerUnitActions takes nothing returns nothing
// 检查单位受到攻击或者计时器到期时运行这个函数,以便于自动给单位添加伤害显示.
    if GetStoredBoolean( CacheValue(), I2S(ConvertHandleInt(GetTriggerUnit())), "HasShowedDamage" ) == false then
        call ShowDamageForPlayerUnitActionsFunc( GetTriggerUnit() )
    endif
endfunction
function TimerCheckShowDamageForPlayerActions takes nothing returns nothing
    local boolexpr b = null
    local group g = CreateGroup() // 选取地图上的所有单位进行检查,一次最高可以选择255个单位.
    call GroupEnumUnitsInRectCounted( g, GetWorldBounds(), b, 255 )
    call DestroyBoolExpr( b )
    call ForGroup( g, function ShowDamageForPlayerUnitGroupActions )
    call DestroyGroup( g )
    set g = null
    set b = null
endfunction
function TimerCheckShowDamageForPlayer takes nothing returns nothing
    local timer t = null // 运行计时器检查玩家伤害显示状态.
    if GetStoredBoolean( CacheValue(), "Maps", "PlayerCheckDamage" ) == false then
        set t = CreateTimer()
        call TimerStart( t, 1.00, true, function TimerCheckShowDamageForPlayerActions )
        call StoreBoolean( CacheValue(), "Maps", "PlayerCheckDamage", true )
    endif
    set t = null
endfunction
// ----> END <----
// ----> 为玩家的所有单位开启伤害显示 <----
function ShowDamageForPlayerUnit takes player p, boolean b, real admg, integer method, handle h returns nothing
// -> 开启/关闭玩家单位伤害显示.
    local boolexpr f = null
    local string name = I2S(ConvertHandleInt(p))
    local trigger dmg_trig = null
    local triggeraction dmg_ta = null
    local boolean flag = GetStoredBoolean( CacheValue(), name, "HasShowedDamage" )
    if b == true then
        if flag == false and GetStoredInteger( CacheValue(), name, "PlayerDamageTrigger" ) == 0 then
            set dmg_trig = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent( dmg_trig, p, EVENT_PLAYER_UNIT_ATTACKED, f )
            set dmg_ta = TriggerAddAction( dmg_trig, function ShowDamageForPlayerUnitActions )
            call StoreInteger( CacheValue(), name, "PlayerDamageTrigger", ConvertHandleInt(dmg_trig) )
            call StoreInteger( CacheValue(), I2S(ConvertHandleInt(dmg_trig)), "TriggerAction", ConvertHandleInt(dmg_ta) )
        else
            set dmg_trig = ConvertTrigger( GetStoredInteger( CacheValue(), name, "PlayerDamageTrigger" ) )
            if dmg_trig !=null and IsTriggerEnabled( dmg_trig) == false then
                call EnableTrigger( dmg_trig )
            endif
        endif
        // ---->> 开启:用计时器检查玩家单位伤害显示状态,建议使用.在一般情况下.当单位受到攻击时会自动添加伤害显示!
        call ExecuteFunc( "TimerCheckShowDamageForPlayer" )
        // ---->> 设置伤害加成数据, 伤害加成因素必须为句柄值.null为无因素.
        call StoreInteger( CacheValue(), name, "AddMethod", method ) // 附加伤害的计算方法
        call StoreInteger( CacheValue(), name, "AddSource", ConvertHandleInt(h) ) // 附加伤害的因素
        call StoreReal( CacheValue(), name, "AddDamage", admg ) // 所附加的伤害
    elseif flag == true then
        set dmg_trig = ConvertTrigger( GetStoredInteger( CacheValue(), name, "PlayerDamageTrigger" ) )
        call DisableTrigger( dmg_trig )
    endif
    call DestroyBoolExpr( f )
    call StoreBoolean( CacheValue(), name, "HasShowedDamage", b )
    set dmg_trig = null
    set f = null
    set dmg_ta = null
endfunction
// ----> ALL END <----
// ----> 经过检查无泄漏发生, 如果在使用的过程出现问题请联系: [email protected]    或者到BBS.WOW8.ORG讨论.

[/jass]
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-24 17:46 , Processed in 0.036793 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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