跳转至

示例

扩展示例

此示例的代码可在123pan中找到

Chat Filter 聊天过滤器

chat-filter
local String = java.import('java.lang.String')

local dicts = java.luaify(String(getConfig('dicts')):split(','))

local hasPermission = function (player)
    local gameRoom = game:getGameRoom()
    return player ~= nil and player:equals(gameRoom:getLocalPlayer())
end

-- Return the first index with the given value (or nil if not found).
local indexOf = function(array, value)
    for i, v in ipairs(array) do
        if v == value then
            return i
        end
    end
    return nil
end

onExit(function ()
    setConfig('dicts', String:join(',', dicts))
end)

registerCommand('addword', '<word>', 'Add a forbidden word, anyone who says it will be hidden and kicked out', function (args, player)
    if hasPermission(player) then
        dicts[#dicts + 1] = args[1]
        reply(player, 'add successfully')
    end
end)

registerCommand('listwords', '', 'List all forbidden words', function (_, player)
    reply(player, String:join(',', dicts))
end)

registerCommand('clearwords', '', 'Clear all forbidden words', function (_, player)
    if hasPermission(player) then
        dicts = {}
        reply(player, 'clear successfully')
    end
end)

registerCommand('removeword', '<word>', 'Remove a forbidden word.', function (args, player)
    if hasPermission(player) then
        local index = indexOf(dicts, args[1])
        if index ~= nil then
            table.remove(dicts, index)
            reply(player, 'remove successfully')
        end
    end
end)

filterEvents('ChatMessageEvent', 'HIGH', function (event)
    local message = event:getMessage()
    local gameRoom = game:getGameRoom()
    if event:getPlayer() ~= nil then
        for _, v in ipairs(dicts) do
            if #v ~= 0 and String(message):contains(v) then
                event:intercept() -- 阻止信息显示 注意这不会阻止在游戏内显示
                if gameRoom:isHost() then
                    reply(gameRoom:getLocalPlayer(), 'kick player: ' .. event:getPlayer():getName())
                    gameRoom:kickPlayer(event:getPlayer())
                end
            end
        end
    end
end)

红警2副官语音

redalert2-voice
local options = {"allies", "soviet", "yuri"}

local alignment = getConfig("alignment") or options[1]

onExit(function ()
    setConfig("alignment", alignment)
end)

local playerDefeatedSound
local unitDamagedSound
local baseDamagedSound
local upgradedCompletedSound
local playerUnitCreatedSound
local playerBuildingConstructedSound
local localPlayerLostSound
local localPlayerWinSound

local function changeAlignment()
    playerDefeatedSound = soundPool:newSound(extension:openInputStream(alignment .. "_player_defeated.ogg"), alignment .. "_player_defeated.ogg")
    unitDamagedSound = soundPool:newSound(extension:openInputStream(alignment .. "_unit_damaged.ogg"), alignment .. "_unit_damaged.ogg")
    baseDamagedSound = soundPool:newSound(extension:openInputStream(alignment .. "_base_damaged.ogg"), alignment .. "_base_damaged.ogg")
    upgradedCompletedSound = soundPool:newSound(extension:openInputStream(alignment .. "_upgraded_completed.ogg"), alignment .. "_upgraded_completed.ogg")
    playerUnitCreatedSound = soundPool:newSound(extension:openInputStream(alignment .. "_player_unit_created.ogg"), alignment .. "_player_unit_created.ogg")
    playerBuildingConstructedSound = soundPool:newSound(extension:openInputStream(alignment .. "_player_building_constructed.ogg"), alignment .. "_player_building_constructed.ogg")
    localPlayerLostSound = soundPool:newSound(extension:openInputStream(alignment .. "_local_player_lost.ogg"), alignment .. "_local_player_lost.ogg")
    localPlayerWinSound = soundPool:newSound(extension:openInputStream(alignment .. "_local_player_win.ogg"), alignment .. "_local_player_win.ogg")
end

extension.settingPanel:add(
    dropdown(options, "选择副官阵营", function ()
        return alignment
    end, function (_, v)
        alignment = v
        changeAlignment()
    end)
)

local playTime = 0
local duration = 100

local Thread = java.import("java.lang.Thread")

local function checkPlayTime(now)
    if now - playTime > duration then
        playTime = now
        return true
    else
        return false
    end
end

filterEvents('GameLoadedEvent', function (_)
    changeAlignment()
end)

filterEvents('GameOverEvent', function (e)
    local room = game:getGameRoom()
    local localPlayer = room:getLocalPlayer()
    if e:getWinTeam() == room:getLocalPlayer():getTeam() and not localPlayer:isDefeated() then
        Thread(function ()
            Thread:sleep(1200)
            localPlayerWinSound:play()
        end):start()
    end
end)

local System = java.import("java.lang.System")

filterEvents('PlayerDefeatedEvent', function (e)
    if not checkPlayTime(System:currentTimeMillis()) then return end
    if e:getPlayer() == game:getGameRoom():getLocalPlayer() then
        localPlayerLostSound:play()
    else
        playerDefeatedSound:play()
    end
end)

-- 下面的事件可能会在将来删除

filterEvents('LocalPlayerUnitDamagedEvent', function (_)
    if checkPlayTime(System:currentTimeMillis()) then unitDamagedSound:play() end
end)

filterEvents('LocalPlayerBaseDamagedEvent', function (_)
    if checkPlayTime(System:currentTimeMillis()) then baseDamagedSound:play() end
end)

filterEvents('LocalPlayerUnitCreatedEvent', function (_)
    if checkPlayTime(System:currentTimeMillis()) then playerUnitCreatedSound:play() end
end)

filterEvents('LocalPlayerBuildingConstructedEvent', function (_)
    if checkPlayTime(System:currentTimeMillis()) then playerBuildingConstructedSound:play() end
end)

filterEvents('LocalPlayerUpgradedCompletedEvent', function (_)
    if checkPlayTime(System:currentTimeMillis()) then upgradedCompletedSound:play() end
end)

山丘之王

thekingofhills
local maxTime = 10 * 60
local gameTime = -1

local Pair = java.import('kotlin.Pair')
local String = java.import('java.lang.String')

-- onExit(function ()
--     setConfig("gameTime", tostring(gameTime))
-- end)


local currentPlayer


filterEvents('GameLoadedEvent', function (_)
    local room = game:getGameRoom()
    -- 建议使用timer, 而不是自行创建Thread,因为lua实际是单线程执行,自行Thread可能导致线程死锁

    local surrenderedPlayers = java.import('java.util.Stack')()

    timer(0, 100, function ()
        if surrenderedPlayers:empty() then
            return
        end
        -- sendSurrender 可能需要部分延迟,此部分还未测试
        room:sendSurrender(surrenderedPlayers:pop())
    end)

    timer(
        0, -- initial delay
        1000, -- period
        function ()
            if currentPlayer ~= nil and gameTime >= 0 then 
                local players = java.luaify(room:getPlayers())
                if gameTime == maxTime or gameTime == 100 or gameTime == 50 or gameTime <= 10 then
                    room:sendSystemMessage("游戏将在: " .. gameTime .. "秒后结束!")
                end
                gameTime = gameTime - 1
                if gameTime == 0 then

                    for _, player in ipairs(players) do
                        if player:getTeam() ~= currentPlayer:getTeam() then
                            surrenderedPlayers:push(player)
                        end
                    end
                    --currentPlayer = nil
                    room:sendSystemMessage("游戏结束!")
                    gameTime = -1
                end 
            end
        end
    )

    -- 在游戏开始时, 若gameMapTransformer不为nil, 则会提前解析map生成XMLMap(具体看源码),解析的map可以进行修改来达到各种目的
    room:setGameMapTransformer(function (_, map) -- 这个地方创建了java Proxy, 第一个参数为Proxy对象,之后才是实际参数,这点需要注意
        local tileWidth = map:getTileWidth()
        local tileHeight = map:getTileHeight()
        local x = (map:getWidth() / 2) * tileWidth
        local y = (map:getHeight() / 2) * tileHeight
        map:addMapObject(
            "add_laboratory", -- id
            "unitAdd", -- type
            x, -- x
            y, -- y
            tileWidth,  -- width
            tileHeight, -- height
            function (_, list)
                list:add(Pair("resetActivationAfter", "1s"))
                list:add(Pair("id", "add_laboratory"))
                list:add(Pair("team", "-1"))
                list:add(Pair("spawnUnits", "laboratory*1"))
                list:add(Pair("activatedBy", "detect_laboratory_death"))
                list:add(Pair("allToActivate", "true"))
                list:add(Pair("showOnMap", "true"))
            end
        )

        map:addMapObject(
            "detect_laboratory_death", -- id
            "unitDetect", -- type
            0, -- x
            0, -- y
            map:getWidth() * tileWidth,  -- width
            map:getHeight() * tileHeight, -- height
            function (_, list)
                list:add(Pair("id", "detect_laboratory_death"))
                list:add(Pair("unitType", "laboratory"))
                list:add(Pair("maxUnits", "0"))
                list:add(Pair("resetActivationAfter", "1s"))
            end
        )

        local players = java.luaify(room:getPlayers())

        for _, player in ipairs(players) do
            local id = "team_detect_laboratory_" .. player:getSpawnPoint()
            map:addMapObject(
                id, -- id
                "unitDetect", -- type
                x, -- x
                y, -- y
                tileWidth,  -- width
                tileHeight, -- height
                function (_, list)
                    list:add(Pair("id", id))
                    list:add(Pair("unitType", "laboratory"))
                    list:add(Pair("minUnits", "1"))
                    list:add(Pair("resetActivationAfter", "1s"))
                    list:add(Pair("team", tostring(player:getSpawnPoint())))
                    list:add(Pair("showOnMap", "true"))
                end
            )
        end
    end)
end)

filterEvents('TriggerActivateEvent', function (e)
    local room = game:getGameRoom()
    local id = e:getId()
    if not room:isHost() then
        return
    end

    if String(id):contains('add_laboratory') then
        gameTime = maxTime
        room:sendSystemMessage("检测到实验室已经被摧毁! 重新生成实验室")
        currentPlayer = nil
    end

    if String(id):startsWith("team_detect_laboratory_") then
        local spawnPoint = tonumber(java.luaify(String(id):replaceFirst("team_detect_laboratory_", "")))
        local players = java.luaify(room:getPlayers())
        for _, player in ipairs(players) do
            if player:getSpawnPoint() == spawnPoint then
                if currentPlayer ~= player then
                    currentPlayer = player
                    room:sendSystemMessage("警告:检测到玩家 [" .. player:getName() .. "] 已经占领了实验室!")
                    gameTime = maxTime
                end
                break
            end
        end
    end
end)

registerCommand("settime", "<time>", "设置游戏最大时长,单位为秒", function (args, player)
    local room = game:getGameRoom()
    -- 判断玩家是否为房主
    if room:getLocalPlayer() == player then
        maxTime = tonumber(args[1]) or 100
        reply(player, "游戏最大时长设置为: " .. maxTime)
    end
end)

filterEvents('PlayerJoinEvent', function (e)
    reply(e:getPlayer(), "欢迎来到山丘之王模式!游戏规则:占领地图中间的实验室一段时间后即可获得胜利")
end)

-- 在游戏地图更改时调用
filterEvents('MapChangedEvent', function (e)
    local room = game:getGameRoom()
    if room:isHost() then
        room:setDisplayMapName("山丘之王♦" .. e:getMapName())
    end
end)

-- 当本地游戏玩家退出游戏时
filterEvents('QuitGameEvent', function (_)
    currentPlayer = nil
end)