CSOL 集成工具
作者

admin

定义武器或装备

多例类 Weapon 用于定义挂机时使用的武器或装备。

字段

name

说明:装备的名称,类型为字符串。

注解:缺省值为 "未知"

number

说明:武器或装备的栏位,可以取下列值:

名称 语义
Weapon.NULL 表示不会被使用的武器或装备,如防弹衣、配件武器
Weapon.PRIMARY 主武器
Weapon.SECONDARY 副武器
Weapon.MELEE 近战武器
Weapon.GRENADE 手雷

注解:该字段缺省值为 Weapon.NULL

attack_button

说明:常规武器或装备的攻击按钮,可取如下值:

名称 语义
Mouse.LEFT 鼠标左键
Mouse.RIGHT 鼠标右键

注解:该字段缺省值为 Mouse.LEFT

switch_delay

说明:武器或装备的切换延迟,单位为毫秒

注解:该字段缺省值为 150

purchase_sequence

说明:武器或装备的购买按键序列,类型为 table

注解:该字段缺省值为 {}。另外,如果有切换 T / CT 阵营武器购买菜单的需要,请像上例中在购买按键序列中添加 J 键。

下例将 weapon 的购买按键序列设置为 B J 8 7

weapon.purchase_sequence = { Keyboard.B, Keyboard.J, Keyboard.EIGHT, Keyboard.SEVEN }

RELOAD_KEY

说明:重新装填按键,可取任意键盘按键,参见 键盘操作

注解:该设定与配置面板中的提供的重新装填按钮设定选项保持一致,缺省值为 Keyboard.R。在使用“圣翼皓印”、“万钧神威”等定制武器时,特殊攻击将通过 RELOAD_KEY 触发

方法

new

说明:构造新武器或装备。

原型:Weapon:new(init)

  • init:初始化列表,类型为 table | nil,当其不缺省为 nil 时,应包含 Weapon 类原型中的各字段初值。除了上文提到的 Weapon 中提供的默认字段外,还可以在其中添加一些自定义的字段。

异常:当 init 类型不正确时,抛出类型错误异常。

注解:在 new 方法的实现中,新武器对象的元表(metatable)会被设置为武器原型 self。因此,当缺省上文中提到的成员字段时,将使用上文提及的认缺省值。下面是 new 的一个简短版本的实现,在有效性校验完成后,将原型武器 self(以 Weapon:new 形式调用时,selfWeapon)的 __index 指向原型武器自身 1,然后将新武器 weapon 的元表设置为 self。后续在访问 weapon 中的缺省成员时,会先访问 weapon 的元表,找到 self 中的 __index 方法,并通过 __index 方法在 self 中找到该缺省值。通过这样的方法,就实现了 Lua 中的继承

原则上,__index 是一个方法(类型为 function),但在 Lua 中提供了一个语法糖,允许我们将 __index 指向某个表(类型为 table)。在试图访问某个缺省值时,将通过调用 __index(指向 function)或访问 __index(指向 table)查阅该缺省值。

function Weapon:new(init)
    local weapon = init or {}
    -->>>对各个字段有效性进行校验,此处省略
    self.__index = self
    setmetatable(weapon, self)
    return weapon
end

下面的例子创建一件名为“幻境!光棱剑”的近战武器,购买按键序列为 B G,切换延迟为 100 ms,使用鼠标左键进行攻击。

Weapon:new{
    name = "幻境!光棱剑",
    number = Weapon.MELEE,
    purchase_sequence = { Keyboard.B, Keyboard.G },
    switch_delay = 100,
    attack_button = Mouse.LEFT,
}

purchase

说明:购买指定的武器或装备。

原型:Weapon:purchase()

说明:鉴于武器购买具有一定特殊性,不应该被其他中断调用过程(如:定期复活或回合重置操作会按下与当前购买操作无关的按键)干扰,因此该方法内部在执行购买时会调用 Runtime:cli 方法关中断

switch

说明:切换至指定的武器或装备,并在切换后等待指定的切换延迟时间。

原型:Weapon:switch()

switch_without_delay

说明:切换至指定的武器或装备,切换后忽略切换延迟时间。

原型:Weapon:switch_without_delay()

在先前版本的实际使用反馈中,发现携带“燃爆 Ignite-10”作为配件装备后,会在购买后出现“自雷”的情况,为此问题,引入了此函数,用于在购买配件武器后,立即切换到其他武器,并通过忽略切换延迟减小对后续切换到其他武器的影响。

abandon

说明:丢弃指定的武器。

原型:Weapon:abandon()

attack

说明:使用指定的常规武器进行一轮攻击。

原型:Weapon:attack()

attack 函数具有默认的实现。当需要定制常规武器攻击方式时,可重写此函数。在重写时需要注意执行一次 attack 的时间一般不超过 10 秒。若对默认的 attack 实现不满意,可以重写 Weapon 类中 attack 的实现。

默认的 attack 在执行攻击操作时,玩家角色朝随机的方向运动,视角水平方向作匀速直线运动,视角垂直方向作简谐运动(上下俯仰),并使用设定的武器攻击按钮进行攻击操作。

以下示例创建了定制武器万钧神威,并重写了 attack 方法。

Weapon:new{
    name = "万钧神威",
    switch_delay = Delay.SHORT,
    number = Weapon.MELEE,
    purchase_sequence = {
        Keyboard.B,
        Keyboard.NINE,
        Keyboard.FOUR
    },
    attack = function (self)
        Mouse:press(Mouse.RIGHT)
        local sensitivity_x = 1 - 0.8 * math.random()
        local sensitivity_y = 1 - 0.8 * math.random()
        local direction = Utility:random_direction()
        local start_time = Runtime:get_running_time()
        local last_switch_time = 0
        local first_throw = false
        local second_throw = false
        repeat
            local current_time = Runtime:get_running_time()
            if current_time - last_switch_time > 1000
            then
                self:switch_without_delay()
                last_switch_time = current_time
            end
            if not Mouse:move_relative(math.floor(direction * 100 * sensitivity_x), math.floor(math.sin(current_time / 1000) * 100 * sensitivity_y), Delay.MINI)
            then
                break
            end
            local duration = Runtime:get_running_time() - start_time
            if not first_throw and 3000 < duration and duration < 6000
            then
                Keyboard:click(Keyboard.R, Delay.SHORT)
                first_throw = true
            end
            if not second_throw and 6000 < duration
            then
                Keyboard:click(Keyboard.R, Delay.SHORT)
                second_throw = true
            end
        until Runtime:get_running_time() - start_time > 7000
        return Mouse:release(Mouse.RIGHT)
    end
}

use

说明:使用指定的特殊武器进行攻击。

原型:Weapon:use()

该函数不提供默认的实现,故需要重写此函数以使用特殊武器进行攻击。在重写时需要注意执行一次 use 的时间一般不超过 10 秒。

以下示例创建了特殊武器圣翼皓印,并重写了 use 方法。需要注意,可以在初始化列表中增加一些自定义的字段(如例中的 discharging 等),并在 use 内使用它们。

Weapon:new{
    name = "圣翼皓印/炽翼魔印",
    switch_delay = 750,
    number = Weapon.GRENADE,
    purchase_sequence = {
        Keyboard.B,
        Keyboard.EIGHT,
        Keyboard.NINE
    },
    discharging = false,
    discharge_start_moment = 0,
    recharge_start_moment = 0,
    DISCHARGE_TIME = 25,
    RECHARGE_TIME = 10,
    use = function (self)
        local current_time = DateTime:get_local_timestamp()
        if not self.discharging and current_time - self.recharge_start_moment > self.RECHARGE_TIME
        then
            self:switch()
            Mouse:click(Mouse.LEFT, 200)
            self.discharging = true
            self.discharge_start_moment = current_time
        elseif self.discharging and current_time - self.discharge_start_moment > self.DISCHARGE_TIME
        then
            self:switch()
            Mouse:move_relative(0, 4000, Delay.NORMAL)
            Keyboard:click(Keyboard.R, 350)
            Mouse:move_relative(0, - 4000, Delay.NORMAL)
            self.discharging = false
            self.recharge_start_moment = current_time
        end
    end
}

武器列表

WeaponList.lua 是执行器在挂机时使用的武器或装备列表文件。集成工具共提供两种挂机模式,分别为默认(default)模式和扩展(extended)模式,以适应不同玩家定制化的需求。

护甲

挂机时,可以自行决定是否定期购买护甲。ArmorWeaponList.lua 中使用的护甲对象。例如,下面的代码将全甲的购买按键序列定义为 B 8 2

Armor = Weapon:new{
    name = "防弹衣+头盔",
    purchase_sequence = { Keyboard.B, Keyboard.EIGHT, Keyboard.TWO }
}

护甲定义为默认模式和扩展模式所共享。

配件武器

在执行器中,配件武器是指挂机过程中携带的辅助武器,例如带有生命配件的手枪等。配件武器仅作辅助之用,永远不会用于攻击。

默认模式下的配件武器购买列表为 DefaultPartWeapons,扩展模式下的配件武器购买列表为 ExtendedPartWeapons

下面的代码向默认模式下的配件武器列表中添加了三件武器,针对扩展模式的配置方式与此完全相同。挂机时,每隔一段时间购买列表中的配件武器(顺序购买,每次购买一件配件武器)。

DefaultPartWeapons = {
    Weapon:new{
        name = "星战前线·加特林",
        number = Weapon.NULL,
        purchase_sequence = { Keyboard.B, Keyboard.J, Keyboard.TWO, Keyboard.FOUR }
    },
    Weapon:new{
        name = "FNP-45战损版",
        number = Weapon.NULL,
        purchase_sequence = { Keyboard.B, Keyboard.J, Keyboard.ONE, Keyboard.TWO }
    },
    Weapon:new{
        name = "燃爆Ignite-10",
        number = Weapon.NULL,
        purchase_sequence = { Keyboard.B, Keyboard.J, Keyboard.EIGHT, Keyboard.SEVEN }
    }
}

鉴于配件武器永远不参与攻击,仅作辅助之用,因此在单个配件武器列表中不建议添加超过 3 件配件武器。

常规武器

常规武器是指采用常规的左键或右键方式进行攻击的武器。默认模式下的常规武器列表为 DefaultConventionalWeapons,扩展模式下的常规武器列表为 ExtendedConventionalWeapons

下面的例子展示了向 DefaultConventionalWeapons 添加一件常规武器,其中 Delay.NORMAL 是预设的延时,其值为 100 毫秒,你也可以将其设定为某一个具体的数字。

DefaultConventionalWeapons = {
    Weapon:new{
        name = "幻境!光棱剑",
        number = Weapon.MELEE,
        purchase_sequence = { Keyboard.B, Keyboard.G },
        switch_delay = Delay.NORMAL,
        attack_button = Mouse.LEFT,
    }
}

你可以向常规武器列表中添加任意数量的武器或装备,挂机时,会从常规武器列表中等概率随机地抽取一件武器使用一段时间(大约为 8 秒),然后抽取下一件武器。如果你需要增大使用某一件武器地概率,则可以在其中多次重复添加该武器。

定制武器

某一些武器(如神鬼开天、万钧神威)同时具备常规攻击和特殊攻击的能力。若需要使用其特殊攻击,则需要在创建该武器对象时,重写默认的 attack 方法。重写 attack 时,建议尽量确保一轮攻击的时间不超过 10 秒(这不是强制性要求,但这样做可以避免被注册在 Runtime 中定期执行回合重置的中断处理函数打断,但一般来说这不会产生很大影响,故若不关心 attack 是否会被打断,可以忽略此建议)。

下面的例子展示了向扩展常规武器列表中添加一件定制武器:

ExtendedConventionalWeapons = {
    Weapon:new{
        name = "神鬼开天/魔神开天",
        switch_delay = Delay.SHORT,
        number = Weapon.MELEE,
        purchase_sequence = {
            Keyboard.B,
            Keyboard.NINE,
            Keyboard.SIX
        },
        attack = function (self)
            Mouse:press(Mouse.RIGHT)
            local sensitivity_x = 1 - 0.8 * math.random()
            local sensitivity_y = 1 - 0.8 * math.random()
            local direction = Utility:random_direction()
            local start_time = Runtime:get_running_time()
            local last_switch_time = 0
            repeat
                local current_time = Runtime:get_running_time()
                if current_time - last_switch_time > 1000
                then
                    self:switch_without_delay()
                    last_switch_time = current_time
                end
                if Mouse:move_relative(math.floor(direction * 100 * sensitivity_x), math.floor(math.sin(current_time / 1000) * 100 * sensitivity_y), Delay.MINI)
                then
                    break
                end
            until Runtime:get_running_time() - start_time > 6000
            Mouse:release(Mouse.RIGHT, 200)
            Mouse:press(Mouse.LEFT, 1000)
            Keyboard:press(Keyboard.R, 200)
            Keyboard:release(Keyboard.R)
            Mouse:release(Mouse.LEFT)
        end
    }
}

特殊武器

与常规武器不同,像圣翼皓印这样的特殊武器没有固定的使用方法,因此必须手动指定。默认模式下使用的特殊武器列表为 DefaultSpecialWeapons,扩展模式下使用的特殊武器列表为 ExtendedSpecialWeapons。圣翼皓印的定义已经在上文中提供过,故此处提供特殊武器【幽浮】控制核心的定义,并将其添加到扩展特殊武器列表。

ExtendedSpecialWeapons = {
    Weapon:new{
        name = "【幽浮】控制核心",
        purchase_sequence = {},
        switch_delay = 500,
        number = Weapon.GRENADE,
        template_name = "【幽浮】控制核心",
        COOL_DOWN_TIME = 60,
        last_start_moment = 0,
        ---为该武器重写 `use` 方法。
        ---@param self Weapon
        use = function (self)
            local current_time = DateTime:get_local_timestamp()
            if (current_time - self.last_start_moment > self.COOL_DOWN_TIME)
            then
                self:switch()
                self.last_start_moment = current_time
                Mouse:click(Mouse.LEFT, 500)
            end
        end
    }
}

特殊武器一般为 4 号位武器,建议在列表中只添加 1 件。

脚注

  1. 要了解有关 Lua 中元表的语法特性,请参阅 Lua 官方指南 13 – Metatables and Metamethods 小节。↩︎