魔兽地图《浩劫余生_4.0》触发自研

特别说明:地图是基于英文版的《浩劫余生》,即《Afterlife v4.0》。

前言:《浩劫余生》的射击触发、装填触发、换枪触发在目前看来都是比较强大的。 源图《Afterlife v4.0》 可以用YDWE打开,但是其中的触发大多是JASS。为此,本羊一遍剖析学习一遍记录如下。

一、地图物编设定

1、所有枪类物品是没有属性的,只有1个装填的技能。同时要注意它的CD间隔组和使用次数。技能编辑器里“飞刀”的施放间隔是8秒。“使用次数”理解为枪类的弹夹容量。

2、一种枪类对应一个独立的单位。说白了,你装备或更换不同的枪,其实质就是切换模型!枪的属性就是单位的属性!例如下面的AK-47,自动射击和连发射击都是不同的单位:

二、装备(更换)武器触发 <难点>

仍然以AK-47为例:

Change to AK 47
    事件
        单位 - 任意单位 使用物品
    条件
        ((操作物品的单位) 的类型) 不等于 AK-47步枪 (连发射击)
        ((操作物品的单位) 的类型) 不等于 AK-47步枪 (自动射击)
        ((被操作物品) 的类型) 等于 AK-47步枪
    动作
        设置 effect[(((触发单位) 的所有者) 的玩家ID)] = MWP_AK47Attachment.mdx
        设置 newHero[(((触发单位) 的所有者) 的玩家ID)] = AK-47步枪 (连发射击)
        自定义代码:   set udg_Hero[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))] = ChangeUnit(GetManipulatingUnit(),udg_newHero[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))],udg_effect[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
        游戏 - 对 (所有玩家) 发送文本信息: (|CFFC70000Your Teammate  + (ColorStr[(((操作物品的单位) 的所有者) 的玩家ID)] + ((((触发单位) 的所有者) 的名字) + ((|r|CFFC70000 +  has equipped ) + ((被操作物品) 的名字)))))

前面都很好理解,就是突然蹦出一句自定义代码,在这句代码中出现了ChangeUnit。这个并不是魔兽自有的触发函数,而是作者自定义的函数,本质是一个复杂的单位替换触发:

function AddOpenWound takes unit berta returns nothing
    local location here
    set here = GetUnitLoc(berta)
    call CreateNUnitsAtLoc( 1, 'u00J', Player(bj_PLAYER_NEUTRAL_EXTRA), here, bj_UNIT_FACING )
    call SetUnitLifeBJ( berta, GetUnitStateSwap(UNIT_STATE_LIFE, berta) + 1 )
    call IssueTargetOrderBJ( GetLastCreatedUnit(), "attack", berta )
    call UnitApplyTimedLifeBJ( 1.00, 'BTLF', GetLastCreatedUnit() )
    call UnitAddAbilityBJ( 'Aloc', GetLastCreatedUnit() )
    call RemoveLocation(here)
endfunction

function AddBrokenLeg takes unit berta returns nothing
    local location here
    set here = GetUnitLoc(berta)
    call CreateNUnitsAtLoc( 1, 'u00K', Player(bj_PLAYER_NEUTRAL_EXTRA), here, bj_UNIT_FACING )
    call SetUnitLifeBJ( berta, GetUnitStateSwap(UNIT_STATE_LIFE, berta) + 1 )
    call IssueTargetOrderBJ( GetLastCreatedUnit(), "attack", berta )
    call UnitApplyTimedLifeBJ( 1.00, 'BTLF', GetLastCreatedUnit() )
    call UnitAddAbilityBJ( 'Aloc', GetLastCreatedUnit() )
    call RemoveLocation(here)
endfunction

function BuffCheck takes unit myUnit returns integer
    local integer mybuff
    set mybuff = 0
    if (GetUnitAbilityLevel(myUnit, 'Bpsi') > 0) then
        set mybuff = mybuff +1
    endif
    if (GetUnitAbilityLevel(myUnit, 'Bssi') > 0) then
        set mybuff = mybuff +2
    endif
    return mybuff
endfunction

function ReAddBuff takes integer cola, unit pepsi returns nothing
if (cola == 1) then
call AddOpenWound(pepsi)
elseif (cola == 2) then
call AddBrokenLeg(pepsi)
elseif (cola == 3) then
call AddOpenWound(pepsi)
call AddBrokenLeg(pepsi)
endif
endfunction

function SetSkills takes integer owner returns nothing
    local integer loopy
    set udg_setskills[owner] = true
    if (udg_SkillA[owner] > 0) then 
    set loopy = 1
    loop
        exitwhen loopy > udg_SkillA[owner]
        call SelectHeroSkill( udg_Hero[owner], 'A005' )
        set loopy = loopy + 1
    endloop
    endif
    
    if (udg_SkillB[owner] > 0) then
    set loopy = 1
    loop
        exitwhen loopy > udg_SkillB[owner]
        call SelectHeroSkill( udg_Hero[owner], 'A00E' )
        set loopy = loopy + 1
    endloop
    endif
    
    if (udg_SkillC[owner] > 0) then
    set loopy = 1
    loop
        exitwhen loopy > udg_SkillC[owner]
        call SelectHeroSkill( udg_Hero[owner], 'A006' )
        set loopy = loopy + 1
    endloop
    endif
    
    if (udg_SkillD[owner] > 0) then
    set loopy = 1
    loop
        exitwhen loopy > udg_SkillD[owner]
        call SelectHeroSkill( udg_Hero[owner], 'A00N' )
        call SelectHeroSkill( udg_Hero[owner], 'A018' )
        call SelectHeroSkill( udg_Hero[owner], 'A019' )
        set loopy = loopy + 1
    endloop
    endif
    
    set udg_setskills[owner] = false
endfunction

//以上所有的函数都是围绕着下面这个核心触发。

function ChangeUnit takes unit oldUnit, integer newUnitId, string attach returns unit
    local real lifetrans
    local real manatrans
    local integer owner
    local integer index
    local unit    newUnit
    local item    indexItem
    local boolean wasHidden
    set lifetrans = GetUnitLifePercent(oldUnit)
    set manatrans = GetUnitManaPercent(oldUnit)
    set owner = GetConvertedPlayerId(GetOwningPlayer(oldUnit))
    set udg_BuffInt[owner] = BuffCheck(oldUnit)
    
    // If we have bogus data, don't attempt the replace.
    if (oldUnit == null) then
        set bj_lastReplacedUnit = oldUnit
        return oldUnit
    endif
    // Hide the original unit.
    set wasHidden = IsUnitHidden(oldUnit)
    call ShowUnit(oldUnit, false)
    // Create the replacement unit.
    set newUnit = CreateUnit(GetOwningPlayer(oldUnit), newUnitId, GetUnitX(oldUnit), GetUnitY(oldUnit), GetUnitFacing(oldUnit))
     // Mirror properties of the old unit onto the new unit.
    //call PauseUnit(newUnit, IsUnitPaused(oldUnit))
    call SetResourceAmount(newUnit, GetResourceAmount(oldUnit))

    // If both the old and new units are heroes, handle their hero info.
    if (IsUnitType(oldUnit, UNIT_TYPE_HERO) and IsUnitType(newUnit, UNIT_TYPE_HERO)) then
        call SetHeroXP(newUnit, GetHeroXP(oldUnit), false)

        set index = 0
        loop
            set indexItem = UnitItemInSlot(oldUnit, index)
            if (indexItem != null) then
                call UnitRemoveItem(oldUnit, indexItem)
                call UnitAddItem(newUnit, indexItem)
            endif

            set index = index + 1
            exitwhen index >= bj_MAX_INVENTORY
        endloop
    endif

    // Remove or kill the original unit.  It is sometimes unsafe to remove
    // hidden units, so kill the original unit if it was previously hidden.
    if wasHidden then
        call KillUnit(oldUnit)
        call RemoveUnit(oldUnit)
    else
        call RemoveUnit(oldUnit)
    endif    
    call DestroyEffectBJ( udg_PlayerAttach[owner] )
    set udg_PlayerAttach[owner] = AddSpecialEffectTargetUnitBJ( "weapon", newUnit, attach )
    call SetUnitColor( newUnit, ConvertPlayerColor(12) )
    call SetUnitLifePercentBJ( newUnit, lifetrans)
    call SetUnitManaPercentBJ( newUnit, manatrans)
    call SelectUnitForPlayerSingle( newUnit, GetOwningPlayer(newUnit) )
    set udg_Hero[owner] = newUnit
    call ReAddBuff(udg_BuffInt[owner],udg_Hero[owner])
    call SetSkills(owner)
    return newUnit
endfunction

如果你的地图中没有失血buff、骨折buff、并且英雄技能也和浩劫余生不一致,那么你可以将 function ChangeUnit 以上的内容都删除,并且删除:

call ReAddBuff(udg_BuffInt[owner],udg_Hero[owner])
call SetSkills(owner)

未完待续……

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据