这是关于 Wurst 和 WurstScript 社区的常规新闻系列文章的第二期。与上一期不同,本期内容简短,重点关注本月的进展。我们打算在未来的所有文章中都采用这种格式。
什么是 Wurst? WurstScript 是一种可编译为 JASS(用于编写《魔兽争霸 3》自定义游戏脚本的语言)的编程语言,它与一套工具一同开发,提供了一致且现代的模组开发体验。它甚至可以与用 vJass 编写的地图协同工作。WurstScript 的设计旨在让难题变得更简单、更优雅,让简单问题变得极其简单。
本期的主题是__“实践中的 WurstScript”__,我们希望展示普通地图如何使用 WurstScript,而不是专注于更高级的语言特性。
buildmap
命令在某些情况下生成无效地图文件的错误。特别感谢 @DD_LegionTN 和 @HappyTauren 的测试和贡献。
本月,我们中的一些人一直在思考并采取行动,以改善 Wurst 开发与 Hive Workshop 之间的统一性。
这方面的一项成就是增加了 Wurst 标签,现在所有与代码相关的提交都已启用该标签。这包括:
我们也很高兴地看到,在这一消息公布之前,就已经有了多个提交!
随着越来越多的社区成员参与进来,您可以期待在不久的将来看到更多与 Wurst 相关的活动。
我们很期待看到您创作的那些有趣但不太适合标准库的作品——更期待看到您在技能提交中能创造出什么样的魔法。如需代码审查反馈,请随时标记 @Frotty 或 @Cokemonkey11。
应读者要求,我们从现在开始将在文章中包含代码片段示例。为了契合本月的主题,这里有一个实用而简单的例子,展示了 Wurst 如何将一个简单的问题变得微不足道:
package SimpleSpell
/// Augments the Warden blink ability to deal damage to units in the target
/// area. Units with low enough health are instead slain.
import Assets
import ClosureForGroups
import EventHelper
import RegisterEvents
constant ID_BLINK = 'A000'
constant BASE_DAMAGE = 100.
constant DAMAGE_RADIUS = 150.
constant SLAY_THRESHOLD = 200.
constant BLINK_RANGE = 1000.
constant EFFECT_POISON = Abilities.poisonStingTarget
constant EFFECT_SLAY = Objects.nightElfBloodArcher
function onEffect()
let caster = GetTriggerUnit()
forUnitsInRange(getSpellTargetPos(), DAMAGE_RADIUS, (unit u) -> begin
if caster.getOwner().isEnemyOf(u.getOwner()) and u.isAlive()
if u.getHP() <= SLAY_THRESHOLD
u.addEffect(EFFECT_SLAY, "origin").destr()
caster.damageTarget(u, SLAY_THRESHOLD * 2.)
else
u.addEffect(EFFECT_POISON, "origin").destr()
caster.damageTarget(u, BASE_DAMAGE)
end)
init
registerSpellEffectEvent(ID_BLINK, function onEffect)
然后,当运行 Wurst 编译器时,上述代码会生成可读性很好的 Jass(见下文)。这只是 Wurst 提供零成本抽象的一个例子,因为内联器最终会将例如 getSpellTargetPos 内联为 2 个局部定义——我们将在未来的文章中更多地讨论这个话题。
function getSpellTargetPos takes nothing returns real
set getSpellTargetPos_return_x = GetSpellTargetX()
set getSpellTargetPos_return_y = GetSpellTargetY()
return getSpellTargetPos_return_x
endfunction
function forUnitsInRange takes real pos_x, real pos_y, real radius, integer c returns nothing
call pushCallback(c)
call GroupEnumUnitsInRange(Group_ENUM_GROUP, pos_x, pos_y, radius, ClosureForGroups_filter)
call popCallback()
endfunction
function onEffect takes nothing returns nothing
local unit caster_2 = GetTriggerUnit()
local real temp_x = getSpellTargetPos()
local real temp_y = getSpellTargetPos_return_y
local integer clVar = alloc_Closure_2()
set caster[clVar] = caster_2
call forUnitsInRange(temp_x, temp_y, 150., clVar)
set caster_2 = null
endfunction
下个月,我们将回归一个更硬核的例子,演示 @compiletime function
s + 表达式及其用途。
我们期待您的评论!像往常一样,我们在 #inwc.de-maps IRC 频道讨论所有与 Wurst 相关的事情。