用JASS简单修改魔兽争霸地图
大学时候,经常用w3mmaster修改一些未加密地图的技能,自娱自乐。有一张地图,神之墓地,有一些改版:“春哥”、“风姐”版,特点是玩家输入“风姐万岁”等特定指令时,英雄会得到若干个随机物品。
想用w3mmaster修改之,但是图经过SLK优化,解压后没有w3u文件(w3mmaster+mpqmaster的改图教程可以参见这里),只有war3map.j,这不就是传说中的JASS脚本文件么?随直接用ue打开,定位“我信春哥!”,找到这段代码:
function Trig_thisisrhick_Actions takes nothing returns nothing
local trigger array iiitttggg
local integer i=1
loop
exitwhen i>12
if GetPlayerController(ConvertedPlayer(i)) == MAP_CONTROL_USER and GetPlayerSlotState(ConvertedPlayer(i)) == PLAYER_SLOT_STATE_PLAYING then
set iiitttggg[i]=CreateTrigger()
set iiitttggg[i+12]=CreateTrigger()
set iiitttggg[i+24]=CreateTrigger()
call TriggerRegisterPlayerChatEvent(iiitttggg[i], ConvertedPlayer(i), "我信春哥!", true )
call TriggerRegisterPlayerChatEvent(iiitttggg[i+12], ConvertedPlayer(i), "信春哥 得永生", true )
call TriggerRegisterPlayerChatEvent(iiitttggg[i+24], ConvertedPlayer(i), "支持飞飞世界", true )
call TriggerAddAction(iiitttggg[i], function iiitttggg_Actions )
call TriggerAddAction(iiitttggg[i+12], function iiitttggg_Actions )
call TriggerAddAction(iiitttggg[i+24], function iiitttggg_Actions )
endif
set i=i+1
endloop
endfunction
显然,这是一个函数定义,其中又调用了一些API。单从函数名上判断,应该是为每个玩家都注册一个由chat命令触发的事件,再看iiitttggg_Actions到底做了什么:
function iiitttggg_Actions takes nothing returns nothing
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerMatching(GetTriggerPlayer(), Condition(function iiitttggg_Func001001002)), function iiitttggg_Func001A )
call DestroyTrigger(GetTriggeringTrigger())
endfunction
继续跟下去,iiitttggg_Func001001002是用来判断当前单位是否是英雄,而iiitttggg_Func001A代码如下:
function iiitttggg_Func001A takes nothing returns nothing
set udg_iiitem = CreateItem(ChooseRandomItemBJ(+3), GetUnitX(GetEnumUnit()), GetUnitY(GetEnumUnit()))
call UnitAddItem( GetEnumUnit(), udg_iiitem )
call DisplayTimedTextToForce( GetPlayersAll(), 10.00, ( GetPlayerName(GetTriggerPlayer()) + ( "获得了由春哥奖励的 " + GetItemName(udg_iiitem) ) ) )
set udg_iiitem = CreateItem(ChooseRandomItemBJ(+3), GetUnitX(GetEnumUnit()), GetUnitY(GetEnumUnit()))
call UnitAddItem( GetEnumUnit(), udg_iiitem )
call DisplayTimedTextToForce( GetPlayersAll(), 10.00, ( GetPlayerName(GetTriggerPlayer()) + ( "获得了由春哥奖励的 " + GetItemName(udg_iiitem) ) ) )
set udg_iiitem = CreateItem(ChooseRandomItemBJ(+8), GetUnitX(GetEnumUnit()), GetUnitY(GetEnumUnit()))
call UnitAddItem( GetEnumUnit(), udg_iiitem )
call DisplayTimedTextToForce( GetPlayersAll(), 10.00, ( GetPlayerName(GetTriggerPlayer()) + ( "获得了由春哥奖励的 " + GetItemName(udg_iiitem) ) ) )
set udg_iiitem = CreateItem(ChooseRandomItemBJ(+9), GetUnitX(GetEnumUnit()), GetUnitY(GetEnumUnit()))
call UnitAddItem( GetEnumUnit(), udg_iiitem )
call DisplayTimedTextToForce( GetPlayersAll(), 10.00, ( GetPlayerName(GetTriggerPlayer()) + ( "获得了由春哥奖励的 " + GetItemName(udg_iiitem) ) ) )
set udg_iiitem = CreateItem(ChooseRandomItemBJ(+9), GetUnitX(GetEnumUnit()), GetUnitY(GetEnumUnit()))
call UnitAddItem( GetEnumUnit(), udg_iiitem )
call DisplayTimedTextToForce( GetPlayersAll(), 10.00, ( GetPlayerName(GetTriggerPlayer()) + ( "获得了由春哥奖励的 " + GetItemName(udg_iiitem) ) ) )
endfunction
顾名思义,ChooseRandomItemBJ就是获取一个随机物品(参数是物品等级),而UnitAddItem将它丢到英雄身上……值得注意的是,iiitttggg_Actions中调用了DestroyTrigger来避免该事件被重复调用,而不是我之前猜想的通过全局变量来记录。
至此,如果要改得更尽兴一点,那就在iiitttggg_Func001A里多call几次相关函数。然后还是照常将war3map.j导回到原地图文件即可。
题外话:JASS居然是Just Another Scripting Syntax的缩写,不由得想到Yaf(Yet another Framework)。