找回密码
 注册/Sign up
搜索
查看: 15|回复: 1

[LUA] 显血,原地遇敌LUA

[复制链接]

发表于 昨天 16:49 | 显示全部楼层 |阅读模式
本帖最后由 fenxo 于 2026-7-26 17:02 编辑

image.png
image.png
功能辅助:
代码覆盖保存到\gmsv\lua\Module\ng.lua 文件下,聊天框输入:“0123456789”开关功能
0:回法兰城
1:显血和原地遇敌
2:不遇敌
3:打卡
4:鉴定
5:修理
6:人物医疗
7:宠物医疗
8:招魂
9:整理背包
--------以下代码保存到\gmsv\lua\Module\ng.lua 文件下,然后在ModuleConfig.lua文件下,用  useModule('ng')  调用
--------以下是代码开始-----------------------------------------

Delegate.RegDelTalkEvent("ng_TalkEvent");
Delegate.RegDelBattleStartEvent("YuanDi_BattleStart");
Delegate.RegDelBattleOverEvent("YuanDi_BattleOver");

local getXiangVar1;
local getXiangVar2;

-- 记录每个玩家的上次回合数
local lastTurn = {};

-- 防重复显示
local lastDisplayMsg = {};
local lastDisplayTime = {};

-- 战斗结束等待标记(延迟5秒恢复走路)
local battleEndWait = {};

-- ============ 获取属性显示字符串 ============
function GetAttrString(charIndex)
    if charIndex == nil or charIndex < 0 then
        return ""
    end
   
    local earth = Char.GetData(charIndex, 21) or 0
    local water = Char.GetData(charIndex, 22) or 0
    local fire = Char.GetData(charIndex, 23) or 0
    local wind = Char.GetData(charIndex, 24) or 0
   
    local attrStr = ""
    if earth > 0 then
        attrStr = attrStr .. "地" .. math.floor(earth / 10)
    end
    if water > 0 then
        attrStr = attrStr .. "水" .. math.floor(water / 10)
    end
    if fire > 0 then
        attrStr = attrStr .. "火" .. math.floor(fire / 10)
    end
    if wind > 0 then
        attrStr = attrStr .. "风" .. math.floor(wind / 10)
    end
   
    if attrStr ~= "" then
        return " [" .. attrStr .. "]"
    end
    return ""
end

-- ============ 看血功能 ============
function ShowEnemyHP(playerIndex)
    if playerIndex == nil or playerIndex < 0 then
        return;
    end
   
    local battleIndex = Battle.GetCurrentBattle(playerIndex)
    if battleIndex == nil or battleIndex < 0 then
        return
    end
   
    local enemyList = {}
   
    for slot = 10, 19 do
        local charIndex = Battle.GetPlayer(battleIndex, slot)
        if charIndex ~= nil and charIndex >= 0 then
            local hp = Char.GetData(charIndex, 12)
            local mp = Char.GetData(charIndex, 13)
            local name = Char.GetData(charIndex, 4000)
            local level = Char.GetData(charIndex, 11)
            
            if name ~= nil then
                name = string.gsub(name, "%?%?", "")
                name = string.gsub(name, "^%s+", "")
                name = string.gsub(name, "%s+$", "")
            end
            
            if hp ~= nil and name ~= nil then
                table.insert(enemyList, {
                    slot = slot,
                    hp = hp,
                    mp = mp,
                    name = name,
                    level = level or 0,
                    charIndex = charIndex
                })
            end
        end
    end
   
    if #enemyList == 0 then
        return;
    end
   
    local slotToIndex = {
        [19] = {row = "前", num = 1},
        [17] = {row = "前", num = 2},
        [15] = {row = "前", num = 3},
        [16] = {row = "前", num = 4},
        [18] = {row = "前", num = 5},
        [14] = {row = "后", num = 1},
        [12] = {row = "后", num = 2},
        [10] = {row = "后", num = 3},
        [11] = {row = "后", num = 4},
        [13] = {row = "后", num = 5},
    }
   
    local displayOrder = {19, 17, 15, 16, 18, 14, 12, 10, 11, 13}
   
    local orderedList = {}
    for _, slot in ipairs(displayOrder) do
        for _, entry in ipairs(enemyList) do
            if entry.slot == slot then
                table.insert(orderedList, entry)
                break
            end
        end
    end
   
    if #orderedList == 0 then
        orderedList = enemyList
    end
   
    local title = "============  敌  方  状  态  ============";
    local liveCount = 0;
    local msgs = {}
    local redMsgs = {}
   
    for idx, entry in ipairs(orderedList) do
        local hp = tonumber(entry.hp) or 0;
        local mp = tonumber(entry.mp) or 0;
        local name = entry.name or ("怪物");
        local level = entry.level or 0;
        local slot = entry.slot
        local charIndex = entry.charIndex
        
        local info = slotToIndex[slot]
        local label = ""
        if info then
            label = "[" .. info.row .. info.num .. "]"
        else
            label = "[" .. slot .. "]"
        end
        
        local attrStr = GetAttrString(charIndex)
        
                if hp > 0 then
                        liveCount = liveCount + 1;
                        local line = label .. " " .. name .. " Lv:" .. level .. " HP:" .. hp .. " MP:" .. mp .. attrStr
                        table.insert(msgs, line)
                        if level == 1 then
                                table.insert(redMsgs, idx)
                        end
                else
                        local line = label .. " " .. name .. " Lv:" .. level .. " 已死亡"
                        table.insert(msgs, line)
                        if level == 1 then
                                table.insert(redMsgs, idx)
                        end
                end
    end
   
    if liveCount > 0 then
        local fullMsg = title .. table.concat(msgs)
        local now = os.time()
        if lastDisplayMsg[playerIndex] == fullMsg and (now - (lastDisplayTime[playerIndex] or 0)) < 3 then
            return
        end
        lastDisplayMsg[playerIndex] = fullMsg
        lastDisplayTime[playerIndex] = now
        
        for i = 1, 20 do
            NLG.TalkToCli(playerIndex, -1, " ", 0, 0)
        end
        NLG.TalkToCli(playerIndex, -1, title, 0, 1)
        
        for i, line in ipairs(msgs) do
            local isRed = false
            for _, redIdx in ipairs(redMsgs) do
                if i == redIdx then
                    isRed = true
                    break
                end
            end
            if isRed then
                NLG.TalkToCli(playerIndex, -1, line, 5, 1)
            else
                NLG.TalkToCli(playerIndex, -1, line, 0, 1)
            end
        end
    end
end

-- ============ 战斗结束后恢复走路(延迟5秒执行) ============
function YuanDi_ResumeWalk(player)
    if player == nil or player < 0 then
        return
    end
    battleEndWait[player] = nil
    Char.UnsetLoopEvent(player)
end

-- ============ 合并循环(原地遇敌走路 + 血量刷新) ============
function YuanDi_MainLoop(player)
    if player == nil or player < 0 then
        return;
    end
   
    -- 如果处于战斗结束等待期,不走路
    if battleEndWait[player] ~= true then
        getXiangVar1 = Char.GetData(player, %对象_香步数%);
        if(getXiangVar1 > 0) then
            NLG.WalkMove(player, 2);
            NLG.WalkMove(player, 6);
        end
    end
   
    -- 血量刷新(检测回合变化)
    local battleIndex = Battle.GetCurrentBattle(player)
    if battleIndex ~= nil and battleIndex >= 0 then
        local currentTurn = Battle.GetTurn(battleIndex)
        if lastTurn[player] == nil or currentTurn ~= lastTurn[player] then
            lastTurn[player] = currentTurn
            ShowEnemyHP(player)
        end
    else
        lastTurn[player] = nil
    end
end

-- ============ 战斗开始 ============
function YuanDi_BattleStart(_battle)
    for slot = 0, 4 do
        local player = Battle.GetPlayer(_battle, slot)
        if player ~= nil and player >= 0 and Char.GetData(player, CONST.对象_血) > 0 then
            Char.UnsetLoopEvent(player)
            lastTurn[player] = nil
            battleEndWait[player] = nil
            Char.SetLoopEvent(nil, "YuanDi_MainLoop", player, 6000)
            ShowEnemyHP(player)
        end
    end
    return 1
end

-- ============ 战斗结束 ============
function YuanDi_BattleOver(_battle)
    for slot = 0, 4 do
        local player = Battle.GetPlayer(_battle, slot)
        if player ~= nil and player >= 0 then
            lastTurn[player] = nil
            
            -- 检查是否开启了原地遇敌
            local steps = Char.GetData(player, %对象_香步数%)
            if steps ~= nil and steps > 0 then
                -- 设置等待标记,阻止走路
                battleEndWait[player] = true
                -- 清除当前循环
                Char.UnsetLoopEvent(player)
-- ===============延迟5秒后恢复走路(重新启动循环)===================================
-- ===============延迟5秒后恢复走路(重新启动循环)===================================
                Char.SetLoopEvent(nil, "YuanDi_ResumeWalk", player, 5000)
-- ===============延迟5秒后恢复走路(重新启动循环)===================================
-- ===============延迟5秒后恢复走路(重新启动循环)===================================
            end
        end
    end
    return 1
end

-- ============ 原地遇敌原功能 ============
function ng_TalkEvent(player, msg, color, range, size)
    if msg == "/hp" or msg == "/血量" then
        ShowEnemyHP(player)
        return 0
    end

    if (msg == "1") then
        getXiangVar1 = Char.GetData(player, %对象_香步数%);
        getXiangVar2 = Char.GetData(player, %对象_香上限%);
        if(getXiangVar1 > 0) then
            Char.SetData(player, %对象_香步数%, 0);
            Char.SetData(player, %对象_香上限%, 0);
            battleEndWait[player] = nil
            Char.UnsetLoopEvent(player)
            NLG.SystemMessage(player, "关闭原地遇敌!");
        else
            Char.SetData(player, %对象_香步数%, 9999);
            Char.SetData(player, %对象_香上限%, 9999);
            battleEndWait[player] = nil
            Char.SetLoopEvent(nil, "YuanDi_MainLoop", player, 6000);
            NLG.SystemMessage(player, "开启原地遇敌!");
        end
    end

    if(msg == "2") then
        local kg = Char.GetData(player, %对象_不遇敌开关%);
        if(kg == 0) then
            Char.SetData(player, %对象_不遇敌开关%, 1);
            NLG.SystemMessage(player, "不遇敌已经开启!");
        else
            Char.SetData(player, %对象_不遇敌开关%, 0);
            NLG.SystemMessage(player, "不遇敌已经关闭!");
        end
    end
   
    if msg == "3" then
        local daka = Char.GetData(player, %对象_打卡%);
        if daka == 0 then
            Char.FeverStart(player);
            NLG.UpChar(player);
            NLG.SystemMessage(player, "恭喜您打卡成功。");
            return ;
        end
        if daka == 1 then
            Char.FeverStop(player);
            NLG.UpChar(player);
            NLG.SystemMessage(player, "恭喜您关闭打卡成功。");
            return ;
        end
    end
   
    if (msg == "0") then
        Char.Warp(player, 0, 1000, 233, 78)
        NLG.SystemMessage(player, "恭喜您已回城。");
        return 0
    end
   
    if (msg == "9") then
        NLG.SortItem(player);
        NLG.SystemMessage(player, "背包整理完毕。");
        return 0
    end
   
    if msg == "4" then
        local Count = 0
        for ItemSlot = 8, 27 do
            local ItemIndex = Char.GetItemIndex(player, ItemSlot)
            if ItemIndex > 0 then
                local money = Char.GetData(player, %对象_金币%);
                local djdj = Item.GetData(ItemIndex, %道具_等级%);
                local kcmb = djdj * 100;
                if Item.GetData(ItemIndex, %道具_已鉴定%) == 0 and money >= (djdj * 100) then
                    Count = Count + 1
                    Char.SetData(player, %对象_金币%, money - kcmb);
                    Item.SetData(ItemIndex, %道具_已鉴定%, 1)
                    NLG.SystemMessage(player, "[系统] 您鉴定的道具等级为" .. djdj .. "级。扣除魔币" .. kcmb .. "G");
                    NLG.SystemMessage(player, "[系统] 你身上的 " .. Item.GetData(ItemIndex, %道具_鉴前名%) .. "已鉴定为 " .. Item.GetData(ItemIndex, %道具_名字%))
                    Item.UpItem(player, ItemSlot);
                    NLG.UpChar(player);
                    return ;
                end
            end
        end
        if Count == 0 then
            NLG.SystemMessage(player, "[系统] 你身上没有需要鉴定的物品【或你的钱不足以鉴定此道具】");
            return;
        end
        return 0
    end
   
    if msg == "5" then
        local Count = 0
        for ItemSlot = 8, 8 do
            local ItemIndex = Char.GetItemIndex(player, ItemSlot)
            local money = Char.GetData(player, %对象_金币%);
            local djdj = Item.GetData(ItemIndex, %道具_等级%);
            local djmz = Item.GetData(ItemIndex, %道具_名字%);
            local djnj = Item.GetData(ItemIndex, %道具_耐久%);
            local djzdnj = Item.GetData(ItemIndex, %道具_最大耐久%);
            local xhnj = djzdnj - djnj
            local jdnj = xhnj * 0.5
            local xlfy = jdnj * 10
            local djlb = Item.GetData(ItemIndex, %道具_类型%);
            if money > xlfy and djzdnj > djnj and djlb >= 0 and djlb <= 14 then
                Count = Count + 1
                Char.SetData(player, %对象_金币%, money - xlfy);
                Item.SetData(ItemIndex, %道具_耐久%, djnj + xhnj);
                Item.UpItem(player, ItemSlot);
                local djnj1 = Item.GetData(ItemIndex, %道具_耐久%);
                local djzdnj1 = Item.GetData(ItemIndex, %道具_最大耐久%);
                Item.SetData(ItemIndex, %道具_耐久%, djnj1 - jdnj);
                Item.SetData(ItemIndex, %道具_最大耐久%, djzdnj1 - jdnj);
                NLG.SystemMessage(player, "[系统] 您修理的装备【" .. djmz .. "】恢复了【" .. xhnj .. "】耐久。扣除魔币【" .. xlfy .. "G】");
                Item.UpItem(player, ItemSlot);
                NLG.UpChar(player);
                return 0
            end
        end
        if Count == 0 then
            NLG.SystemMessage(player, "[系统] 你道具栏第一格没有要恢复耐久的装备或者您的修理魔币不足。");
            return 0
        end
        return 0
    end
   
    if msg == "8" then
        local ZH = Char.GetData(player, 170);
        local money = Char.GetData(player, %对象_金币%);
        local LV = Char.GetData(player, %对象_等级%);
        local ZHMB = ZH * 100;
        local ZHMBKC = ZHMB * LV
        if ZH <= 0 then
            NLG.SystemMessage(player, "你没有掉魂。");
        end
        if money >= ZHMBKC and ZH > 0 then
            Char.SetData(player, %对象_金币%, money - ZHMBKC);
            Char.SetData(player, 170, ZH - ZH);
            Char.FeverStop(player);
            NLG.UpChar(player);
            NLG.SystemMessage(player, "招魂完成。招魂数量为【" .. ZH .. "】费用为【" .. ZHMBKC .. "】魔币。");
        end
        if money < ZHMBKC then
            NLG.SystemMessage(player, "连钱都没有你还招魂,一边尿尿玩泥巴去吧。【招魂价格计算 掉魂*1000*等级】");
        end
    end
   
    if msg == "6" then
        local shoushang = Char.GetData(player, %对象_受伤%);
        local money = Char.GetData(player, %对象_金币%);
        if(Char.GetData(player, %对象_受伤%) < 1) then
            NLG.SystemMessage(player, "您未受伤。");
            return;
        end
        if money >= 100 and (Char.GetData(player, %对象_受伤%) > 0 and Char.GetData(player, %对象_受伤%) < 26) then
            Char.SetData(player, %对象_受伤%, shoushang - shoushang);
            Char.SetData(player, %对象_金币%, money - 100);
            NLG.UpdateParty(player);
            NLG.UpChar(player);
            NLG.SystemMessage(player, "恭喜你治疗完毕。");
            NLG.SendGraphEvent(player, 45, 0);
            NLG.SystemMessage(player, "扣除100魔币。");
            return;
        end
        if money >= 200 and (Char.GetData(player, %对象_受伤%) > 24 and Char.GetData(player, %对象_受伤%) < 51) then
            Char.SetData(player, %对象_受伤%, shoushang - shoushang);
            Char.SetData(player, %对象_金币%, money - 200);
            NLG.UpdateParty(player);
            NLG.UpChar(player);
            NLG.SystemMessage(player, "恭喜你治疗完毕。");
            NLG.SendGraphEvent(player, 45, 0);
            NLG.SystemMessage(player, "扣除200魔币。");
            return;
        end
        if money >= 300 and (Char.GetData(player, %对象_受伤%) > 49 and Char.GetData(player, %对象_受伤%) < 76) then
            Char.SetData(player, %对象_受伤%, shoushang - shoushang);
            Char.SetData(player, %对象_金币%, money - 300);
            NLG.UpdateParty(player);
            NLG.UpChar(player);
            NLG.SystemMessage(player, "恭喜你治疗完毕。");
            NLG.SendGraphEvent(player, 45, 0);
            NLG.SystemMessage(player, "扣除300魔币。");
            return;
        end
        if money >= 400 and (Char.GetData(player, %对象_受伤%) > 74 and Char.GetData(player, %对象_受伤%) < 101) then
            Char.SetData(player, %对象_受伤%, shoushang - shoushang);
            Char.SetData(player, %对象_金币%, money - 400);
            NLG.UpdateParty(player);
            NLG.UpChar(player);
            NLG.SystemMessage(player, "恭喜你治疗完毕。");
            NLG.SendGraphEvent(player, 45, 0);
            NLG.SystemMessage(player, "扣除400魔币。");
            return;
        end
        NLG.SystemMessage(player, "对不起!您的魔币不足,治疗价格为【白伤100】【黄伤200】【紫伤300】【红伤400】!");
        return 0
    end
   
    if msg == "7" then
        cwzhiliao(player)
        return ;
    end
    return 1;
end

function cwzhiliao(_meIndex)
    local PetIndex = Char.GetPet(_meIndex, 0)
    if PetIndex < 0 then
        NLG.SystemMessage(_meIndex, "请确认您的宠物栏第一栏位有宠物...")
        return
    end
    local cwss = Char.GetData(PetIndex, CONST.对象_受伤)
    if cwss and cwss >= 1 then
        Char.SetData(PetIndex, CONST.对象_受伤, 0)
        Pet.UpPet(_meIndex, PetIndex)
        NLG.SystemMessage(_meIndex, "[个人]恭喜,您的宠物恢复了往日雄风。。。")
        return
    end
    NLG.SystemMessage(_meIndex, "[系统]您的宠物未受伤。")
end

function cwzhiliao2(_meIndex, _toIndex, _itemslot)
    local PetIndex0 = Char.GetPet(_meIndex, 0)
    local PetIndex1 = Char.GetPet(_meIndex, 1)
    local PetIndex2 = Char.GetPet(_meIndex, 2)
    local PetIndex3 = Char.GetPet(_meIndex, 3)
    local PetIndex4 = Char.GetPet(_meIndex, 4)
   
    if(PetIndex0 > 0) then
        Char.SetData(PetIndex0, %对象_血%, Char.GetData(PetIndex0, %对象_最大血%));
        Char.SetData(PetIndex0, %对象_魔%, Char.GetData(PetIndex0, %对象_最大魔%));
        Pet.UpPet(_meIndex, PetIndex0);
    end
    if(PetIndex1 > 0) then
        Char.SetData(PetIndex1, %对象_血%, Char.GetData(PetIndex1, %对象_最大血%));
        Char.SetData(PetIndex1, %对象_魔%, Char.GetData(PetIndex1, %对象_最大魔%));
        Pet.UpPet(_meIndex, PetIndex1);
    end
    if(PetIndex2 > 0) then
        Char.SetData(PetIndex2, %对象_血%, Char.GetData(PetIndex2, %对象_最大血%));
        Char.SetData(PetIndex2, %对象_魔%, Char.GetData(PetIndex2, %对象_最大魔%));
        Pet.UpPet(_meIndex, PetIndex2);
    end
    if(PetIndex3 > 0) then
        Char.SetData(PetIndex3, %对象_血%, Char.GetData(PetIndex3, %对象_最大血%));
        Char.SetData(PetIndex3, %对象_魔%, Char.GetData(PetIndex3, %对象_最大魔%));
        Pet.UpPet(_meIndex, PetIndex3);
    end
    if(PetIndex4 > 0) then
        Char.SetData(PetIndex4, %对象_血%, Char.GetData(PetIndex4, %对象_最大血%));
        Char.SetData(PetIndex4, %对象_魔%, Char.GetData(PetIndex4, %对象_最大魔%));
        Pet.UpPet(_meIndex, PetIndex4);
    end
    return ;
end
-----------------完----------------------------

您需要登录后才可以回帖 登录 | 注册/Sign up

本版积分规则

手机版|cgmsv引擎论坛

GMT+8, 2026-7-27 04:15 , Processed in 0.032904 second(s), 5 queries , Gzip On, Redis On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表