找回密码
 点一下
查看: 1486|回复: 13

求教一下有人知道内建AOE技能的影响范围和代码enum选择的误差值么?

[复制链接]
发表于 2009-6-26 17:48:47 | 显示全部楼层 |阅读模式
就是内建技能比如暴风雪战争践踏,它们对于单位的判断似乎是碰到沿就算,而对于用EnumUnitsInRange之类的选择的话,是算中心坐标点的

这两者间的误差是多少呢?和碰撞体积或其他有关么?
发表于 2009-6-28 15:11:50 | 显示全部楼层
我记得好像跟碰撞体积有关.
我以前用刀阵旋风和T配合做特效.同样是300范围,但是有些受到刀阵旋风伤害的单位没有添加特效.
触发器选取范围内单位应该是判断单位X,Y坐标是否在范围内.
而技能的应该是单位的碰撞体积边缘坐标是否在范围内.
仅仅是觉得
回复

使用道具 举报

 楼主| 发表于 2009-6-28 21:39:49 | 显示全部楼层
对,我就是这个意思

我想知道这个误差值……
回复

使用道具 举报

发表于 2009-6-28 22:03:27 | 显示全部楼层
误差... 每个单位的碰撞是不一样的.. 我弄了一个800碰撞的农民..
效果如下
未命名.jpg

你看见农民绿了吗... 这个不是误差值的问题 是单位碰撞的问题 如果单位碰撞都是一样的 可以算出来 如果不一样就...
回复

使用道具 举报

发表于 2009-6-28 22:12:20 | 显示全部楼层
AOE技能计算碰撞
AOE技能实际范围 为 技能预设范围 + 单位碰撞体积
比如 AOE 实际300
单位碰撞31
那么 单位距离释放点 小于等于331的时候都会命中

选取 只是计算 2单位所在点之间距离 判断是否 小于等于选取距离
比如选取300范围
那么 只有距离小于等于300 才会被选中
301也不会被选中

自己做的实验
结果不会有问题
回复

使用道具 举报

发表于 2009-7-2 21:14:01 | 显示全部楼层
是和碰撞体积有关
要改进的话,可以稍加大一两百的范围,然后用再算碰撞的IsUnitInRangeXY来判断
回复

使用道具 举报

发表于 2009-7-3 00:12:33 | 显示全部楼层
原来IsUnitInRangeXY是计算碰撞的啊……
回复

使用道具 举报

 楼主| 发表于 2009-7-3 14:27:06 | 显示全部楼层
嗯,几个IsUnitInRange都是算碰撞的,最近才知道

那 kook大 这个误差值就正好是是碰撞体积么?
回复

使用道具 举报

发表于 2009-7-3 14:42:15 | 显示全部楼层
function DamageAreaTimed_DamageFunc takes nothing returns nothing
    local integer dMin = SYS_GroupTempData[1000]
    local integer dMax = SYS_GroupTempData[1001]
    local integer Cr = SYS_GroupTempData[1002]
    local integer Cp = SYS_GroupTempData[1003]
    local integer Count = SYS_GroupTempData[1004]
    local integer CountLeft = SYS_GroupTempData[1005]
    local integer DamType = SYS_GroupTempData[1006]
    local integer beIndex = SYS_GroupTempData[1007]
    local integer iCond = SYS_GroupTempData[1008]
    local boolean ShowStr = SYS_GroupTempData[1009]>0
    local integer Dam
    if(GetFilterUnit()==SYS_GroupUnit)then
        return false
    endif
    if(Count>0 and CountLeft<=0)then
        return false
    endif
    if(IsUnitInRangeXY(GetFilterUnit(),SYS_GroupX,SYS_GroupY,SYS_GroupR))then
        if(not(TargetUnitCheck(GetFilterUnit(),SYS_GroupUnit,iCond)))then
            return false
        endif
        if(beIndex>0 and not(ExecuteBoolexpr(SYS_Boolexpr[beIndex])))then
        return false
    endif
    set SYS_GroupTempData[1005] = SYS_GroupTempData[1005] - 1
        set Dam = GetRandomInt(dMin,dMax)
        if(Dam==0)then
            return false
        endif
        call DamageUnit(SYS_GroupUnit,GetFilterUnit(),Dam,Cr,Cp,DamType,ShowStr)
        return false
    endif
endfunction

function DamageAreaTimed_Loop takes nothing returns nothing
    local integer tmIndex = GetTimerIndex(GetExpiredTimer())
    local integer MaxCp = 1000000
    local integer dMin = SYS_TimerData_I00[tmIndex]
    local integer dMax = SYS_TimerData_I01[tmIndex]
    local integer tmp = SYS_TimerData_I02[tmIndex]
    local integer Cr = Mod(tmp,101)
    local integer Cp = Mod_EX(tmp,101*(MaxCp+1),101)
    local integer Count = tmp/((MaxCp+1)*101)
    local integer tmp2 = SYS_TimerData_I03[tmIndex]
    local integer DamType = tmp2/8192
    local integer bIndex = Mod(tmp2,8192)
    local integer iCond = SYS_TimerData_I04[tmIndex]
    local group gp = CreateGroup()
    set SYS_GroupUnit = SYS_TimerData_U02[tmIndex]
    set SYS_GroupTarget = SYS_TimerData_U03[tmIndex]
    set SYS_GroupX = SYS_TimerData_R00[tmIndex]
    set SYS_GroupY = SYS_TimerData_R01[tmIndex]
    set SYS_GroupR = SYS_TimerData_R02[tmIndex]
    set SYS_GroupTempData[1000] = dMin
    set SYS_GroupTempData[1001] = dMax
    set SYS_GroupTempData[1002] = Cr
    set SYS_GroupTempData[1003] = Cp
    set SYS_GroupTempData[1004] = Count
    set SYS_GroupTempData[1005] = Count
    set SYS_GroupTempData[1006] = DamType
    set SYS_GroupTempData[1007] = bIndex
    set SYS_GroupTempData[1008] = iCond
    call GroupEnumUnitsInRange(gp,SYS_GroupX,SYS_GroupY,SYS_GroupR+200.0,Condition(function DamageAreaTimed_DamageFunc))
    call DestroyGroup(gp)
    set gp = null
endfunction
回复

使用道具 举报

发表于 2009-7-3 14:43:59 | 显示全部楼层
function DamageAreaTimed takes real time,integer iCond,integer DamType,unit su,unit tu,real x,real y,real r,integer dMin,integer dMax,integer cr,integer cp,integer count,integer beIndex returns integer
    local integer tmIndex = GetTimerIndex(GetTimer())
    local integer MaxCp = 1000000
    set SYS_TimerData_U02[tmIndex] = su
    set SYS_TimerData_U03[tmIndex] = tu
    set SYS_TimerData_I00[tmIndex] = dMin
    set SYS_TimerData_I01[tmIndex] = dMax
    set SYS_TimerData_I02[tmIndex] = IConfig(cr,0,100) + 101*IConfig(cp,0,MaxCp) + 101*(MaxCp+1)*count
    set SYS_TimerData_I03[tmIndex] = IConfig(beIndex,0,8191) + DamType*8192
    set SYS_TimerData_I04[tmIndex] = iCond
    set SYS_TimerData_R00[tmIndex] = x
    set SYS_TimerData_R01[tmIndex] = y
    set SYS_TimerData_R02[tmIndex] = r
    call TimerStart(SYS_Timer[tmIndex],RMax(time,0.0),false,function DamageAreaTimed_Loop)
    return tmIndex
endfunction
回复

使用道具 举报

发表于 2009-7-3 14:45:03 | 显示全部楼层
function IsUnitInvulnerable takes unit u returns boolean
    return GetUnitAbilityLevel(u,'Avul')>0
endfunction

function IsUnitMagicImmune takes unit u returns boolean
    return IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)
endfunction

function IsUnitPhysicalImmune takes unit u returns boolean
    return IsUnitType(u,UNIT_TYPE_ETHEREAL)
endfunction

function GetTuCheckCond takes integer i,integer cType returns boolean
    return Mod(i,cType*2)/cType==1
endfunction

function DoTuCheckCond takes integer i,integer cType,boolean chk,integer chkValue returns integer
    local integer c = 0
    local integer p = 0
    if(GetTuCheckCond(i,cType))then
        set c = 1
        if(chk)then
            set p = 1
    endif
    endif
    return IMax(chkValue/2,c)*2 + IMax(Mod(chkValue,2),p)
endfunction

function TargetUnitCheck takes unit cu,unit su,integer i returns boolean
&#160;&#160;&#160;&#160;local integer chkValue = 0
&#160;&#160;&#160;&#160;local boolean ally = IsUnitAlly(cu,GetOwningPlayer(su))
&#160;&#160;&#160;&#160;local boolean enemy = IsUnitEnemy(cu,GetOwningPlayer(su))
&#160;&#160;&#160;&#160;local boolean alive = GetUnitState(cu,UNIT_STATE_LIFE)>0
&#160;&#160;&#160;&#160;if(IsUnitInvulnerable(cu))then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if(not(GetTuCheckCond(i,SUF_Invulnerable)))then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return false
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;if(IsUnitMagicImmune(cu))then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if(not(GetTuCheckCond(i,SUF_MagicImmune)))then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return false
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;if(IsUnitType(cu,UNIT_TYPE_STRUCTURE))then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if(not(GetTuCheckCond(i,SUF_Building)))then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return false
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;if(GetTuCheckCond(i,SUF_NoneSelf) and cu==su)then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return false
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;if(GetTuCheckCond(i,SUF_NoneTarget) and cu==SYS_GroupTarget)then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return false
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;set chkValue = 0
&#160;&#160;&#160;&#160;set chkValue = DoTuCheckCond(i,SUF_Alive,alive,chkValue)
&#160;&#160;&#160;&#160;set chkValue = DoTuCheckCond(i,SUF_Dead,not(alive),chkValue)
&#160;&#160;&#160;&#160;if(chkValue==2)then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return false
&#160;&#160;&#160;&#160;elseif(chkValue==0 and not(alive))then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return false
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;//============
&#160;&#160;&#160;&#160;set chkValue = 0
&#160;&#160;&#160;&#160;set chkValue = DoTuCheckCond(i,SUF_AttackAble,not(IsUnitPhysicalImmune(cu)),chkValue)
&#160;&#160;&#160;&#160;set chkValue = DoTuCheckCond(i,SUF_MagicAble,not(IsUnitMagicImmune(cu)),chkValue)
&#160;&#160;&#160;&#160;if(chkValue==2)then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return false
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;//============
&#160;&#160;&#160;&#160;set chkValue = 0
&#160;&#160;&#160;&#160;set chkValue = DoTuCheckCond(i,SUF_Ally,ally,chkValue)
&#160;&#160;&#160;&#160;set chkValue = DoTuCheckCond(i,SUF_Enemy,enemy,chkValue)
&#160;&#160;&#160;&#160;set chkValue = DoTuCheckCond(i,SUF_Nature,not(ally) and not(enemy),chkValue)
&#160;&#160;&#160;&#160;if(chkValue==2)then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return false
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;//============
&#160;&#160;&#160;&#160;set chkValue = 0
&#160;&#160;&#160;&#160;set chkValue = DoTuCheckCond(i,SUF_IsHero,IsUnitType(cu,UNIT_TYPE_HERO),chkValue)
&#160;&#160;&#160;&#160;set chkValue = DoTuCheckCond(i,SUF_NotHero,not(IsUnitType(cu,UNIT_TYPE_HERO)),chkValue)
&#160;&#160;&#160;&#160;if(chkValue==2)then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return false
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;//============
&#160;&#160;&#160;&#160;set chkValue = 0
&#160;&#160;&#160;&#160;set chkValue = DoTuCheckCond(i,SUF_Flying,IsUnitType(cu,UNIT_TYPE_FLYING),chkValue)
&#160;&#160;&#160;&#160;set chkValue = DoTuCheckCond(i,SUF_Ground,IsUnitType(cu,UNIT_TYPE_GROUND),chkValue)
&#160;&#160;&#160;&#160;if(chkValue==2)then
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return false
&#160;&#160;&#160;&#160;endif
&#160;&#160;&#160;&#160;return true
endfunction
回复

使用道具 举报

发表于 2009-7-3 14:45:08 | 显示全部楼层
结束
回复

使用道具 举报

发表于 2009-7-3 15:16:27 | 显示全部楼层
EFF 我崇拜你....
回复

使用道具 举报

发表于 2009-7-3 21:04:23 | 显示全部楼层
正好这个是从地图里面单独拿出来的代码。。能看懂的自己拿回去用
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-7-22 00:28 , Processed in 0.051934 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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