铁血丹心

 找回密码
 我要成为铁血侠客
搜索
查看: 307|回复: 10

[lua复刻] 黑山群侠传学习-CEvent学习1

[复制链接]
 楼主| 发表于 2024-6-16 09:52 | 显示全部楼层 |阅读模式

马上注册,结交更多侠友!

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x
# 在场景中加入事件

前面已经学会了如何在大地图中加入新的场景地图。有了场景地图当然是在场景地图中加入事件,认加入的场景融入金庸世界,SO接下来就是学习如何在场景中加入新的事件。黑山群侠传的事件是采用CEvent模式,而龙的传人是直接使用的UPedit中的事件编辑器。两者有点区别,对于开发者来说就是使用不同的方式增加,修改,删除事件。黑山中加入事件过程如下。

## 学学已经有的事件

黑山群侠传的事件文件为Lua脚本,存放位置是游戏主目录/SCRIPT/CEvent/目录下,打开此目录可以看到有8651个事件。所以如果你要新加事件就可以从8652开始,我为了做一个区分从10000开始加事件。可以查看其它事件,学习如何加入新事件,每个场景地图中都会有很多事件,比如jymain.lua中非杨过玩家创建角色后就显示的通过`CallCEvent(691)`调用的SCRIPT/CEvent/691.lua,打开691.lua可以看下做了什么。
```bash
--OEVENTLUA[691] = function()
  --instruct_66(42)
  -- 设定小村事件0事件属性
  instruct_3(-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
  -- 设定当前人物在子场景位置, 也就是主角在小村中的位置
  instruct_19(16, 31)
  -- 设定人物向左上移动
  instruct_40(2)
  instruct_0()
  -- 从一个位置移动到另外一个位置
  instruct_30(16, 31, 9, 31)
  instruct_0()
  -- 黑屏
  instruct_14()
  -- 更改小村62号事件位置显示人物,8250为北丑,这里的贴图编号需要除以2才是实际的
场景图号
  instruct_3(-2, 62, 0, 0, 0, 0, 0, 8250, 8250, 8250, -2, -2, -2)
  instruct_3(-2, 4, 0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2)
  instruct_0()
  instruct_3(-2, 2, 1, 0, 690, 0, 0, 6086, 6086, 6086, -2, -2, -2)
  instruct_0()
  -- 添加物品
  instruct_32(174, 400)
  instruct_0()
  instruct_32(234, 1)
  instruct_0()
  instruct_32(182, 1)
  instruct_0()
  -- 设置2个位置显示人物,南贤与北丑
  instruct_3(-2, 4, 1, 0, 695, 0, 0, 8250, 8250, 8250, -2, -2, -2)
  instruct_3(-2, 3, 1, 0, 694, 0, 0, 5098, 5098, 5098, -2, -2, -2)
  instruct_3(-2, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
  instruct_3(-2, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
  -- 一些场景设置不能进入
  instruct_39(19)
  instruct_39(101)
  instruct_39(36)
  instruct_39(28)
  instruct_39(93)
  instruct_0()
  instruct_13()
--end
```
上面都是通过调用各种命令函数实现某种功能,其中出现最多的就`instruct_0()`清除对话显示,`instruct_3()`更改场景地图中特定事件属性(比如特定位置贴图,是否可进行事件等),`instruct_39()`关闭场景进入功能。这些命令都是在jymain.lua中实现的,具体函数也都有注释,注释不清楚的猜一下也一般都知道在干什么。

## 依葫芦画瓢

1. 先来个最简单的事件。在SCRIPT/CEvent.lua下面加入一个新文件10000.lua。在10000.lua中加入下面代码。
```bash
TalkEx("你好!!", 1, 0)
TalkEx("你是谁?", 0, 1)
do return end
```
2. 场景地图中加入事件:打开UPedit,打开自己新加的场景地图或要加入事件的场景地图,操作层选择事件层。指定位置点击鼠标右键加入事件,设置事件属性。能否通过表示能否激活,事件编号可以不改,事件1填10000就是上面创建的脚本事件,这里使用静态贴图,因此开始贴图/结束贴图/开始贴图都填写同一个数字就可以了,这个数字就是贴图查看中查到的贴图编号 * 2。注意这里贴图编号需要 * 2,因为底层C会将这个数字除以2再去找贴图编号。完成后保存,注意新创建一个新存档确定新加入的事件是否成功添加到场景地图上。
3. 我按上面步骤添加事件后,事件是添加成功了,显示的文字不是我脚本中加入的文字,因此又出现了一个脚本中文字编码问题。使用记事本打开10000.lua发现编码格式是utf8,需要另存为ANSI游戏中就可以完美显示了。
4. 前面的对话发现人物是胡斐,这里的对话人物又是如何选择的拉。用UPedit查看就可以看到胡斐的编号是1,换一个张三丰编号5或灭绝编号6可以试试,人物就会做相应改变。

## 下面再学习下其它事件

1. 宝箱获取物品
```bash
instruct_2(112, 1)  --得到一本罗汉拳
Cls()  --清屏
instruct_3(-2, -2,0,0,0,0,0,2492,2492,2492,-2,-2,-2)  --箱子打开且不能再得到物品
do return end
```
2. 请求张三丰加入
```bash
if instruct_9() then  --要求加入
  Cls()  --清屏
  TalkEx("我正在寻找一些书,要在江湖上到处走动,张真人如果不嫌弃,不妨与小弟同行,也为你无聊人生添加一些乐趣。", 0, 5)  --对话
  Cls()  --清屏
  TalkEx("好吧,反正生活无趣。", 5, 0)  --对话
  Cls()  --清屏
  if instruct_20() then  --判断队伍是否已满
    Cls()  --清屏
    TalkEx("你的队伍已满,我就直接去小村吧。", 5, 0)  --对话
    Cls()  --清屏
    instruct_3(-2, -2,0,0,0,0,0,0,0,0,0,-2,-2)  --修改场景事件
    instruct_3(70, 107,1,0,10002,0,0,5380,5380,5380,-2,-2,-2)  --修改场景事件
    Cls()  --清屏
    do return end  --无条件结束事件

  end
  instruct_10(5)  --加入队伍
  Cls()  --清屏
  instruct_14()  --场景变黑
  instruct_3(-2, -2,0,0,0,0,0,0,0,0,0,-2,-2)  --修改场景事件
  Cls()  --清屏
  instruct_13()  --场景变亮
  Cls()  --清屏
  do return end  --无条件结束事件
end
TalkEx("你太厉害了,在下告辞。", 0, 5)  --对话
Cls()  --清屏
instruct_3(-2, -2,-2,-2,2,-2,-2,-2,-2,-2,-2,-2,-2)  --修改场景事件
do return end
```
3. 商店买东西
```bash
instruct_64()  --小宝买东西
Cls()  --清屏
do return end
-- 进入instruct_64()看看具体细节
--无酒不欢:商店数据
function instruct_64()
  -- 商家头像编号
  local headid = 223
  local id = -1
  -- 找到当前是那家客栈
  for i = 0, JY.ShopNum - 1 do
    if CC.ShopScene[i].sceneid == JY.SubScene then
      id = i
    end
  end
  if id < 0 then
    return
  end
  TalkEx("这位小哥,看看有什么需要的,小店卖的东西价钱绝对公道。", headid, 0,"商家")

  -- 获取当前商家物品信息
  local menu = {}
  for i = 1, 6 do
    local thingid = JY.Shop[id]["物品" .. i]
    if thingid ~= -1 then
      menu[i] = {}
      menu[i][1] = string.format("%-12s %5d", JY.Thing[thingid]["名称"], JY.Shop[id]["物品价格" .. i])
      menu[i][2] = nil
      if JY.Shop[id]["物品数量" .. i] > 0 then
        menu[i][3] = 1
      else
        menu[i][3] = 0
      end
    end
  end

  --3书以前没有混元
  if JY.Base["天书数量"] < 3 and id == 0 then
    menu[5][3] = 0
  end
  
  -- 准备绘制商品显示界面
  local x1 = (CC.ScreenW - 9 * CC.DefaultFont - 2 * CC.MenuBorderPixel) / 2
  local y1 = (CC.ScreenH - 5 * CC.DefaultFont - 4 * CC.RowPixel - 2 * CC.MenuBorderPixel) / 2
  -- 返回选择物品序号
  local r = ShowMenu(menu, #menu, 0, x1, y1, 0, 0, 1, 1, CC.DefaultFont, C_ORANGE, C_WHITE)
  -- 下面数据已经没有使用了
  --[[
  local itemJC = {}
  itemJC[0] = {38, 12, 28, 14, 68, -1, 400, 100, 80, 500, 6000, -1}
  itemJC[1] = {48, 0, 29, 15, 90, -1, 400, 100, 100, 500, 1000, -1}
  itemJC[2] = {54, 3, 32, 16, 159, -1, 400, 100, 100, 600, 600, -1}
  itemJC[3] = {63, 7, 33, 17, 175, -1, 400, 200, 120, 600, 800, -1}
  itemJC[4] = {27, 9, 34, 22, 69, -1, 2000, 50, 130, 400, 8000, -1}]]
  if r > 0 then
    -- 穷逼没钱
    if instruct_31(JY.Shop[id]["物品价格" .. r]) == false then
      TalkEx("非常抱歉,你身上的钱似乎不够。", headid, 0,"商家")
    -- 买东西成功
    else
      JY.Shop[id]["物品数量" .. r] = JY.Shop[id]["物品数量" .. r] - 1
      instruct_32(CC.MoneyID, -JY.Shop[id]["物品价格" .. r])
      instruct_32(JY.Shop[id]["物品" .. r], 1)
      TalkEx(JY.Person[0]["外号"].."买了小店的东西,保证绝不后悔。", headid, 0,"商家")
    end
  end

  -- 这里的d_leave我也还没有猜出来是干什么的
  for i,v in ipairs(CC.ShopScene[id].d_leave) do
    instruct_3(-2, v, 0, -2, -1, -1, 939, -1, -1, -1, -2, -2, -2)
  end
```

## 看一条完整的天书事件线

1. UPedit找到65唐诗山洞,点击事件层,点击编号为1的事件,确定相关脚本为39.lua,打开看看
```bash
-- 可以看到对话还可以以instruct_1(179, 0, 1)方式进行,其中179是UPedit中的对话事件编辑器中的对话引用,179对话内容是:你是谁,在这做什么
instruct_1(179,0,1);   --  1(1):[AAA]说: 你是谁,在这做什么?
instruct_0();          -- 和前面的Cls()一样
say()                  -- 以故事形式显示文字
-- 教程说要70道德才能加入,但看代码没有对道德进行判断的地方
-- 这里的instruct_9()带参数,但实际上jymain.lua中的instruct_9()不带参数,应当是旧版本需要参数,后面的instruct_20也是不需要参数的
-- 这里还有个加道德的命令instruct_37()
if instruct_9(0,93) ==true then    --  9(9):是否要求加入?否则跳转到:Label0
    instruct_1(191,0,1);   --  1(1):[AAA]说: 看你也无家可归,和我一起走吧,路上也
照应。
    instruct_0();   --  0(0)::空语句(清屏)
    if instruct_20(32,0) ==false then    --  20(14):队伍是否满?是则跳转到:Label2        instruct_37(2);   --  37(25):增加道德2
    instruct_1(192,37,0);   --  1(1):[狄云]说: 好吧!如果你不怕被我这个不幸之人连
话。

        instruct_3(-2,-2,0,0,0,0,0,0,0,0,0,0,0);   --  3(3):修改事件定义:当前场景
场景事件编号
        instruct_3(104,81,1,0,956,0,0,7232,7232,7232,-2,-2,-2);   --  3(3):修改事
义:场景[钓鱼岛]:场景事件编号 [81]
        instruct_10(37);   --  10(A):加入人物[狄云]
        instruct_0();   --  0(0)::空语句(清屏)

  -- 接下来的埋葬丁典事件8012开启
  instruct_3(62,13,1,0,0,0,0,6700,6700,6700,0,0,0);   --修改破庙事件
  instruct_3(62,12,1,0,8012,0,0,6696,6696,6696,0,0,0);    --修改破庙事件
        do return end
    end
instruct_37(2);   --  37(25):增加道德2
say("你的队伍已满,我就直接去小村吧。",37,0);
instruct_3(-2,-2,0,0,0,0,0,0,0,0,0,0,0);   --  3(3):修改事件定义:当前场景:当前场>景事件编号
instruct_3(104,81,1,0,956,0,0,7232,7232,7232,-2,-2,-2);   --  3(3):修改事件定义:>场景[钓鱼岛]:场景事件编号 [81]
instruct_3(70, 7,1,0,125,0,0,5090,5090,5090,-2,-2,-2)  --修改场景事件
instruct_3(70, 8,1,0,125,0,0,5092,5092,5092,-2,-2,-2)  --修改场景事件

instruct_0();   --  0(0)::空语句(清屏)

-- 队伍满了,狄云去小村还是会开启埋葬丁典事件
instruct_3(62,13,1,0,0,0,0,6700,6700,6700,0,0,0);   --修改破庙事件
instruct_3(62,12,1,0,8012,0,0,6696,6696,6696,0,0,0);    --修改破庙事件
    do return end
end

```
2. 看了上面的发现加狄云没有道德要求,那么看下加萧中慧有没有道德限制。找到河洛客栈加萧中慧事件脚本200.lua,关键看下要求加入部分,可以明显看到60道德判断。这里队伍如果已经满了,萧中慧只会吐槽一句不会自己去小村,估计是因为如果带她去小村会触发种树事件,如果她自己去小村了,就容易出BUG了。看了这里完全可以给狄云加入条件加上70道德判断。200.lua开始还判断也队伍中有没有小田田,有小田田会调戏萧咪咪,还会打一架。打架也简单,`WarMain(132, 0)`。UPedit中找到战斗数据编辑中的132,就是和小田田打萧中慧。旁边还会显示战斗地图。
```bash
if instruct_9() then  --是否要求加入
  TalkEx("得红颜相伴,闯荡江湖,真*乃平生快事啊。", 0, 1)  --对话
  Cls()  --清屏
  if instruct_28(0,60,200) then --判断品德是否在范围之内
    instruct_26(1,3,1,0,0)  --修改场景事件
    instruct_26(1,4,1,0,0)  --修改场景事件
    instruct_26(1,5,1,0,0)  --修改场景事件
    instruct_3(104, 64,1,0,978,0,0,7248,7248,7248,-2,-2,-2)  --修改场景事件
    instruct_37(1)  --增加品德
    if instruct_20() == false then  --判断队伍是否已满
      instruct_14()  --场景变黑
      instruct_3(-2, -2,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
      Cls()  --清屏
      instruct_13()  --场景变亮
      JY.Person[77]["资质"] = JY.Person[0]["资质"]
      --萧中慧选择内力属性
      local r = JYMsgBox("请选择", "请选择萧中慧的内力属性", {"阴内","阳内","调和"}, 3, 77)
      if r == 1 then
        instruct_49(77, 0)
        Cls()  --清屏
      elseif r == 2 then
        instruct_49(77, 1)
        Cls()  --清屏
      elseif r == 3 then
        instruct_49(77, 2)
        Cls()  --清屏
      end
      instruct_2(162, 1)
      Cls()  --清屏
      instruct_10(77)  --加入队伍
      do return end  --无条件结束事件

    end
    TalkEx("你的队伍满了啊,真没有诚意。", 77, 0)  --对话
    Cls()  --清屏
    do return end  --无条件结束事件

  end
  TalkEx("哎呀,不行,我爸爸说了,*闯荡江湖要和正人君子在一*起,你……,还是算了吧。", 77, 0)  --对话
  Cls()  --清屏
  do return end  --无条件结束事件
end
Cls()  --清屏
```
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2024-6-16 10:51 | 显示全部楼层
修改狄云加入条件:
3. 给狄去入队加入道德限制
```
-- 39.lua
-- 是否要求加入之后加入一行当前道德判断
    if instruct_9(0,93) ==true then    --  9(9):是否要求加
入?否则跳转到:Label0
      if instruct_28(0,70,200) then --判断品德是否在范围之

      ...
      -- 最后的do return end后加入道德不够时的对话和一个end表示if语句结束
      say("我是个不幸之人,就不连累你了。",37,0);
    end
  do return end
```
再次打开游戏,建立一个新角色或读取一个道德值50以下存档,再
去加狄去,就会说“我是个不幸之人,就不连累你了。“。然后再开
一个道德70以上的档,或直接在691.lua中加入一句`instruct_37(50)`,再新建立一个标准人物档,去了少林或其它门派拿入门功法
后就可以去找狄云测试一下,应当就能正常加入了。最后还需要把
691.lua中加道德的语句删除,不然开局就是100道德了。
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2024-6-19 07:21 | 显示全部楼层
非常好的教程,楼主辛苦!

PS:似乎论坛不支持markdown?
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2024-6-19 07:23 | 显示全部楼层
顺便确认一下cevent是这个转出来的不:

https://github.com/godka/sfe-kdef
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2024-6-26 23:02 | 显示全部楼层
wo cao niu bi a  yidian dou meiyou kan dong
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2024-7-6 21:32 | 显示全部楼层
4. 继续开启后续
第一个是104场景的81事件,脚本是956.lua,看看956.lua是什么。看后确定是回到现实是最后一战,是否要求狄云加入战斗的选择,不是主线任务不管。
第二个事件是62场景地图上触发的8012.lua,看看8012.lua。是给丁典上香,上完香就当前事件就改成了8011.lua,叹息一下丁典死亡。另外还启动了一个当前场景的8001.lua事件,看看。这里是打宝象事件,代码粘出来看看,有个判断人物是否在队要求,狄云不在队是不能触发的。
```bash
--破庙103,与宝象的对话事件
--OEVENTLUA[8001] = function()

  say("妈巴羔子的,这破地方,什么都没有,饿死老子了。",160,0,"宝象");   --[宝象]:妈巴羔子的,这破地方,甚么都没有,饿死老子了。
  if not inteam(37) then  --如果队伍没有狄云,则直接退出
    return;
  end
  say( "你是谁?妈巴羔子的,贼王八蛋!",160,0,"宝象");    --[宝象]:你是谁?妈巴羔子的,贼王八蛋!
  say("L<这人虽作和尚打扮,但却污言秽语,多半是个凶悍之徒>",0,1);    --[主角]:〈这人虽作和尚打扮,但却污言秽语,多半是个凶悍>之徒。〉
  say("在下只是途经此地,并无恶意。",0,1);    --[主角]:在下只是途经此地,并无恶意。
  say("癞痢头阿三,你去给我找些吃的东西来,大师父重重有赏,有没有肥猪?",160,0,"宝象"); --[宝象]:癞痢头阿三,你去给我找些吃的东>西来,大师父重重有赏,有没有肥猪?
  say("这破庙荒山野岭没肥猪……L<这和尚,居然还杀生吃肉,定为恶人无疑>",0,1);    --[主角]:这破庙荒山野岭没肥猪……〈这和尚,居然>还杀生吃肉,定为恶人无疑〉
  say("喂,叫你去找些吃的东西来,嘀咕嘀咕想干什么。你不听话,瞧佛爷不要了你的狗命?",160,0,"宝象"); --[宝象]:喂,叫你去找些吃的>东西来,嘀咕嘀咕想干甚么。你不听话,瞧佛爷不要了你的狗命?
  say("L<欺人太甚,是否要教训一下他?>",0,1);    --[主角]:〈欺人太甚,是否教训他〉
  instruct_0();   --  0(0)::空语句(清屏)

  if instruct_5() ==true then    --  5(5):是否选择战斗?
    say("你这和尚真是毫不讲理。",0,1);  --[主角]:你这和尚真是毫不讲理。
    say("哈哈,好极,好极!老子不仅喜欢不讲理,还喜欢吃人肉。你这肌肉,吃起来一定很美味。",160,0,"宝象");   --[宝象]:哈哈,好极>,好极!老子不仅喜欢不讲理,还喜欢吃人肉。你这肌肉,吃起来一定很美味。
    say("恶和尚,受死!",0,1);    --[主角]:恶和尚,受死!

    -- 这里是第246场战斗,斗宝象
    if WarMain(246) == false then
      instruct_15();      --战斗失败,死亡
      return;
    end
    instruct_3(-2,16,0,0,0,0,0,0,0,0,0,0,0);    --清除宝象的贴图
    light()

    instruct_37(1)  --增加品德

    say("这恶僧果然有些门道,难怪敢如此嚣张。但是今日幸遇上我,也算是替天行道。",0,1);  --[主角]:这恶僧果然有些门道,难怪敢如此>嚣张。但是今日幸遇上我,也算是替天行道。
    say("这边似乎还留有一些东西。",0,1);  --[主角]:这边似乎还留有一些东西
    instruct_2(174,200);  --获取银两200
    instruct_0();   --  0(0)::空语句(清屏)

    say("这衣服怪丢了可惜,比我这身好,还是留给我吧。",37,5); --[狄云]:这衣服怪丢了可惜,比我这身好,还是留给我吧。
    say("的确比你这光着身子的好。",0,1);    --[主角]:的确比你这光着身子的好
    say("呵呵。多谢丁大哥。不,不是丁大哥。",37,5); --[狄云]:呵呵。多谢丁大哥。不,不是丁大哥。
    instruct_0();   --  0(0)::空语句(清屏)


    instruct_3(60,31,0,0,0,0,8002,0,0,0,0,0,0);   --修改龙门客栈门口路过事件
    instruct_3(60,32,0,0,0,0,8002,0,0,0,0,0,0);
  end
--end
```
5. 到龙门客栈
门口事件改成8002.lua脚本。这里有点奇怪的是事件能否通过设置的是0,不是1。我尝试改成1后,狄云不在也是不能触发的。这里的8002.lua还是比较精彩的,有很多人物移动和贴图改变的语句。还有一个没有见过的场景移动`instruct_25()`,最后开启雪山进入条件方法更是特别,是类似于可全局保存的变量一样,有点像单片机中的写入到flash操作,不过这个就当是写入到grp,idx文件。
```bash
  -- 从客栈门口走到掌柜前
  if JY.Base["人X1"] == 24 then     --两个触发地方的移动方式不一样
    instruct_30(-1,9,0,0);
    instruct_30(-5,1,0,0);
  else
    instruct_30(0,9,0,0);
    instruct_30(-5,1,0,0);
  end

  instruct_3(-2,36,1,0,0,0,0,9222,9222,9222,0,0,0);     --水笙贴图
  instruct_3(-2,37,1,0,0,0,0,8904,8904,8904,0,0,0);     --汪啸风贴图

  instruct_25(4,-15,0,0);   --场景移动
  
  -- 最后开启雪山进入条件为1,未完成此事件前雪山是不开启的
  SetS(86, 9, 10, 5, 1);    --判断触发雪山事件
```
这里的人物移动有点意思,提出来说:
```bash
    -- 这里的移动指令,地图也会跟着移动,有点像大地图上人物移动一样,人物贴图会保持在中心位置
    -- 移动方向是一个点到另外一个点
    instruct_30(-1,9,0,0);
    -- 从(-1, 9)移动到(0,0),X增加1,Y减少9。从UPeidt场景地图可知起点是(24,26),移动到(25, 17)
    instruct_30(-5,1,0,0);
    -- 再从(25,17)移动到(30,16)掌柜面前,这里因为有桌子等建筑层会阻碍人物移动,因此移动分成了这2个步骤才顺利移动到掌柜面前。
```
再研究下`instruct_30`指令的实现,还是比较有趣的,只看一下其中一个方向的移动,因为4个方向都类似。
```bash
  if x1 < x2 then
    for i = x1 + 1, x2 do
      local t1 = lib.GetTime()
      -- 实际移动指令
      instruct_30_sub1(1)
      local t2 = lib.GetTime()
      -- 其它的都只是为防止眼睛反映过来加的延时
      if t2 - t1 < CC.PersonMoveFrame then
        lib.Delay(CC.PersonMoveFrame - (t2 - t1))
      end
    end

    -- 下面是instruct_30_sub1()实现,它有一个参数,表示方向,1 x增加,2 x减少, 3 Y增加, 4Y减少
  function instruct_30_sub1(direct)
    -- 主要是是x1,y1坐标改变后,再重绘场景地图
    local x, y = nil, nil
    AddMyCurrentPic()
    x = JY.Base["人X1"] + CC.DirectX[direct + 1]
    y = JY.Base["人Y1"] + CC.DirectY[direct + 1]
    JY.Base["人方向"] = direct
    JY.MyPic = GetMyPic()
    DtoSMap()
    -- 判断是否可以通过,当前点有没没有建筑?
    if SceneCanPass(x, y) == true then
      JY.Base["人X1"] = x
      JY.Base["人Y1"] = y
    end
    -- 有没有超过场景地图限制
    JY.Base["人X1"] = limitX(JY.Base["人X1"], 1, CC.SWidth - 2)
    JY.Base["人Y1"] = limitX(JY.Base["人Y1"], 1, CC.SHeight - 2)
    -- 重绘场景地图
    DrawSMap()
    ShowScreen()
    return 1
  end
```
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2024-7-6 21:33 | 显示全部楼层
6. 龙门客栈中的镜头移动
`instruct_25()`与前面`instruct_20()`类似。就是将当前画面中特定人物置于中心位置,这是人类习惯导致的,看图时会更关注中心位置内容。因此这个指令可以用于切换画面中焦点位置,凸出画面中某位说话人物。
```bash
  say("采花淫贼,赶快出来受死!",305,0, "水笙");    --[水笙]:采花淫贼,赶快出来受死
  -- 将焦点移动到说话之人水笙身上
  instruct_25(-4,15,0,0);
```
7. 龙门客栈后面部分

```bash
  -- 清除人物
  instruct_3(-2,39,0,0,0,0,0,0,0,0,0,0,0);      --清除水笙贴图
  instruct_3(-2,37,0,0,0,0,0,0,0,0,0,0,0);      --清除汪啸风贴图
  instruct_3(-2,35,0,0,0,0,0,0,0,0,0,0,0);      --清除狄云贴图
  instruct_3(-2,38,0,0,0,0,0,0,0,0,0,0,0);      --清除血刀老祖贴图
  
  -- 水笙和狄去被抓去雪山
  instruct_3(2,8,1,0,0,0,0,9224,9224,9224,0,0,0);   --修改雪山水笙贴图
  instruct_3(2,7,1,0,0,0,0,9228,9228,9228,0,0,0);   --修改雪山狄云贴图
  instruct_13();

  say("L<糟糕,狄兄弟也被掳走了。似乎往雪山方向走了>",0,5);  --主角:〈糟糕,狄兄弟
也被掳走了。似乎往雪山方向走了〉
  -- 队友离队函数
  instruct_21(37);    --狄云离队
  instruct_0();   --  0(0)::空语句(清屏)

  -- 雪山开启开关打开,这个开关类似一把锁,此事件之前都是锁着的,因为雪山进门事件41.lua就是判断这里的开关打开没有
  SetS(86, 9, 10, 5, 1);    --判断触发雪山事件
```
8. 来到雪山

```bash
    -- 这里就是前面龙门客栈事件才能打开的锁,没打开前会被直接传送出雪山
    --龙门客栈事件还未触发前不可进入
    if GetS(86, 9, 10, 5) ~= 1 then
      say( "这地方好冷,还是出去吧。",0,1);   --[主角]:这地方好冷,还是出去吧。
      JY.Base["人X1"] = JY.Scene[JY.SubScene]["出口X1"];
      JY.Base["人Y1"] = JY.Scene[JY.SubScene]["出口Y1"];
      return;
    end

    -- 三个有间客栈传言,感觉放到龙门客栈事件后要好些
栈]:场景事件编号 [5]
    instruct_3(3,6,1,0,643,0,0,-2,-2,-2,-2,-2,-2);   --  3(3):修改事件定义:场景[有间客
栈]:场景事件编号 [6]
    instruct_3(3,8,1,0,643,0,0,-2,-2,-2,-2,-2,-2);   --  3(3):修改事件定义:场景[有间客
栈]:场景事件编号 [8]
    -- 清除当前进门事件
    instruct_3(-2,0,0,0,0,0,0,0,0,0,0,0,0);   --  3(3):修改事件定义:当前场景:场景事件>编号 [0]
    instruct_3(-2,1,0,0,0,0,0,0,0,0,0,0,0);   --  3(3):修改事件定义:当前场景:场景事件>编号 [1]
    instruct_3(-2,2,0,0,0,0,0,0,0,0,0,0,0);   --  3(3):修改事件定义:当前场景:场景事件>编号 [2]
    -- 自动触发雪山事件后续
    -- 人物移动与聚焦
    instruct_30(27,49,27,34);   --  30(1E):主角走动27-49--27-34
    instruct_25(27,34,27,30);   --  25(19):场景移动27-34--27-30
    -- 下面就是一堆对话

    -- 血刀老祖求助,正邪分支
    if DrawStrBoxYesNo(-1, -1, "是否要帮助血刀老祖?", C_WHITE, CC.DefaultFont) then  --是/否
        instruct_37(-2);   --  37(25):增加道德-2
        instruct_1(208,0,1);   --  1(1):[???]说: 为了天书,只好如此了!
        instruct_0();   --  0(0)::空语句(清屏)
   
        -- 然后就是为战斗做准备, 这里有个血量翻倍设定,根据的是592人物判断,看看592是谁, 使用UPedit看了一下是独孤求败
        --花铁干血量翻倍
    JY.Person[52]["血量翻倍"] = JY.Person[592]["血量翻倍"]

        -- 这里的战斗指令用的是instruct_6, 而非之前的warMain看下有什么区别
        if instruct_6(42,4,0,0) ==false then    --  6(6):战斗[42]是则跳转到:Label1
            instruct_15(0);   --  15(F):战斗失败,死亡
            instruct_0();   --  0(0)::空语句(清屏)
            do return; end
        end    --:Label1

```
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2024-7-6 21:34 | 显示全部楼层
9. warMain()和`instruct_6()`区别

```bash
-- 只是对WarMain()简单封装,还多了2个无用参数,无语
function instruct_6(warid, tmp, tmp, flag)
  return WarMain(warid, flag)
end
-- 来都来了,看看WarMain(warid, flag)
--战斗主函数^M
function WarMain(warid, isexp)^M
  -- 加地图数据
  WarLoad(warid)      --初始化战斗数据^M
  -- 加队友
  WarSelectTeam_Enhance() --选择我方(优化版)^M
  -- 加敌人
  WarSelectEnemy()    --选择敌人^M
  ^M
  -- 开挂人物, 向量翻倍人物
  Health_in_Battle()    --无酒不欢:血量翻倍^M

-- 看看如何向量翻倍的
--无酒不欢:血量翻倍函数^M
function Health_in_Battle()^M
  for i = 0, WAR.PersonNum - 1 do^M
    local pid = WAR.Person[i]["人物编号"]^M
    --加一个变量避免重复翻倍^M
    --就是用一个R数据中的人物属性控制人物生命最大值与生命是否翻倍
    if JY.Person[pid]["血量翻倍"] > 1 and WAR.HP_Bonus_Count[pid] == nil then^M
      JY.Person[pid]["生命最大值"] = JY.Person[pid]["生命最大值"] * JY.Person[pid][">血量翻倍"]^M
      JY.Person[pid]["生命"] = JY.Person[pid]["生命"] * JY.Person[pid]["血量翻倍"]^M
      WAR.HP_Bonus_Count[pid] = 1^M
    end^M
    --无酒不欢:非我方自动运功^M
    if inteam(pid) == false or WAR.Person[i]["我方"] == false then^M
      if JY.Person[pid]["天赋内功"] > 0 then^M
        JY.Person[pid]["主运内功"] = JY.Person[pid]["天赋内功"]^M
      end^M
      if JY.Person[pid]["天赋轻功"] > 0 then^M
        JY.Person[pid]["主运轻功"] = JY.Person[pid]["天赋轻功"]^M
      end^M
    end^M
  end^M
end^M
```
10. 战斗胜利后继续

```bash
      -- 这里修改场景贴图没有通过instruct_3改变事件层属性,而是直接使用instruct_17将之前的人物贴图改为0,也就是删除了
      instruct_17(-2,1,24,31,0);   --  17(11):修改场景贴图:当前场景层1坐标18-1F
      instruct_17(-2,1,27,27,0);   --  17(11):修改场景贴图:当前场景层1坐标1B-1B
      instruct_17(-2,1,30,34,0);   --  17(11):修改场景贴图:当前场景层1坐标1E-22
      -- 当了坏人后水笙找主角单练
      say("你这个恶人,杀了我爹爹,我和你拼了!",305,4,"水笙")

    DrawStrBoxWaitKey("水笙愤怒之极,激发了体内的潜能", C_GOLD, CC.DefaultFont,nil,LimeGreen)

    if WarMain(252, 0) == false then  --主角单挑水笙
      Cls()  --清屏
      instruct_15()  --死亡
      Cls()  --清屏
      do return end  --无条件结束事件
    end
    -- 打了水笙后删除水笙,又使用了一个新函数null, 进入会发现就是对instruct_3的封装
    null(-2, 8)
    -- 狄云也跑了
    dark()
    null(-2,7)  --无酒不欢:删除狄云
    light()
   
    -- 后面都是一些之前学习过,是否加花铁干,得到一些物品等
```

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2024-7-6 21:34 | 显示全部楼层
11. 正线

```bash
-- 废话不多说,就是干
    if instruct_6(7,5,0,0) ==false then    --  6(6):战斗[7]是则跳转到:Label4
        instruct_0();   --  0(0)::空语句(清屏)
        instruct_15(0);   --  15(F):战斗失败,死亡
        do return; end
        instruct_0();   --  0(0)::空语句(清屏)
    end
    instruct_3(-2,3,1,0,0,0,0,8744,8744,8744,0,0,0);      --血刀老祖向后转
    -- 又是一段剧情后,狄去属性增加,如果是畅想狄云,就是主角自己属性增加
    local xid = 37;
    if JY.Base["畅想"] == 37 then
      xid = 0
    end
    QZXS("狄云攻防轻各能力提升三十点");   --(系统提示:狄云攻防轻能力各提升三十点)
    AddPersonAttrib(xid, "攻击力", 30)
    AddPersonAttrib(xid, "防御力", 30)
    AddPersonAttrib(xid, "轻功", 30)

    QZXS("狄云五系兵器值各提升十点");   --(系统提示:狄云四系兵器值各提升十点)
    AddPersonAttrib(xid, "拳掌功夫", 10)
    AddPersonAttrib(xid, "指法技巧", 10)
    AddPersonAttrib(xid, "御剑能力", 10)
    AddPersonAttrib(xid, "耍刀技巧", 10)
    AddPersonAttrib(xid, "特殊兵器", 10)
    --狄云洗血刀
    instruct_35(37,1,63,0)

    instruct_3(-2,7,1,0,8003,0,0,9228,9228,9228,0,0,0);   --新增事件8003,重新加入狄云
    -- 最后就是给本鬼头刀法,然后各加各家,各找各妈

     say(JY.Person[0]["外号"]..",感谢你的救命之恩,这本刀法你拿去吧,后会有期。",96,0);   --  1(1):[???]说:
    instruct_0();   --  0(0)::空语句(清屏)
    instruct_2(164,1);   --  2(2):得到物品[鬼头刀法][1]
    instruct_0();   --  0(0)::空语句(清屏)
  say("爹……我想……",305,4, "水笙");
  say("想你妈了吧?我们这就回去。",96,0);
  say("……狄大哥……再见了。",305,4, "水笙");
    instruct_14();   --  14(E):场景变黑
    instruct_17(-2,1,24,31,0);   --  17(11):修改场景贴图:当前场景层1坐标18-1F
    instruct_17(-2,1,27,27,0);   --  17(11):修改场景贴图:当前场景层1坐标1B-1B
    instruct_17(-2,1,30,34,0);   --  17(11):修改场景贴图:当前场景层1坐标1E-22
    instruct_17(-2,1,25,29,0);   --  17(11):修改场景贴图:当前场景层1坐标19-1D
```

12. 清水和石碑那里有3个事件43,45,46.lua, 一个一个来

```bash
-- 43.lua
-- 就一句话
TalkEx("由于人类的浪费和污染,水*资源已经枯竭,这是世界上*剩下的唯一一盆淡水了,请*珍惜。", 0, 2)  --对话

--46.lua
-- 也只有一句话, 就不贴出来了

-- 45.lua
    if instruct_4(206,0,331) ==true then    --  4(4):是否使用物品[唐诗选集]?否则跳转到
:Label0

      say("咦,有字显示出来了。", 0,1);
      say("连城诀……天宁寺大佛后……", 0,1);
      say("终于有天书的下落了,赶紧过去看看吧。", 0,1);
      say("似乎还有一个类似剑谱的东西。", 0,1);

      Cls();
    -- 特定位置显示文字
    local x = CC.ScreenW/2;
    local y = CC.ScreenH/2;
    local color = C_GOLD;
    local size = CC.Fontbig;
    local offx = (#"床前明月光,疑是地上霜" - #"静夜思")*size/4;

    DrawString(x+offx,y,"静夜思",color,size);  --静夜思
    ShowScreen();
    lib.Delay(1000);
    DrawString(x,y+size,"床前明月光,疑是地上霜",color,size);  --床前明月光,疑是地上

    ShowScreen();
    lib.Delay(1000);
    DrawString(x,y+size*2,"举头望明月,低头思故乡",color,size);  --举头望明月,低头思
故乡
    ShowScreen();
    lib.Delay(2000);

    --狄云第三武功洗为连城剑法
    if inteam(37) then
      say("是连城剑诀,没想到竟然在这唐诗之中。", 37,0);
      instruct_35(37,2,114,0);
      DrawStrBoxWaitKey("狄云学会武功【G连城剑法O】", C_ORANGE, CC.DefaultFont, 2)
    end

    instruct_2(237,1);    --得到连城剑诀
   
    -- 后面就是更改客栈和天宁寺事件,也就是连城决的最后事件了
```
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2024-7-6 21:35 | 显示全部楼层
13. 天宁寺拿书,没啥难点

```bash
instruct_3(-2, -2,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_40(0)  --主角面向右
instruct_25(20,47,20,39)  --场景移动
TalkEx("哗!这里可真热闹,想必各位都是为那《连城诀》而来的吧。但是很对不起,这东西我>先定下了,没你们的份了。", 0, 1)  --对话
Cls()  --清屏
if WarMain(93, 0) == false then  --战斗开始
  instruct_15()  --死亡
  Cls()  --清屏
  Cls()  --清屏
  do return end  --无条件结束事件

end
instruct_3(-2, 1,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 2,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 3,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 4,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 5,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 6,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 7,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 8,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 9,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 10,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 11,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 12,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 13,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 14,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 15,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_3(-2, 16,0,0,0,0,0,0,0,0,0,0,0)  --修改场景事件
instruct_19(20,47)
Cls()  --清屏
instruct_13()  --场景变亮
do return end
```
49.lua获取天书,根据狄云是否在队伍判断是否获得神照经
```bash
--重新修改获取连城诀事件
--OEVENTLUA[49] = function()
    instruct_3(-2,-2,0,0,0,0,0,0,0,0,0,0,0);   --  3(3):修改事件定义:当前场景:当前场>景事件编号
    instruct_2(146,1);   --  2(2):得到物品[连城诀][1]

    -- 得到连城诀后江湖传言更改
    instruct_3(3,5,1,0,645,0,0,-2,-2,-2,-2,-2,-2);   --  3(3):修改事件定义:场景[有间>客栈]:场景事件编号 [5]
    instruct_3(3,6,1,0,645,0,0,-2,-2,-2,-2,-2,-2);   --  3(3):修改事件定义:场景[有间>客栈]:场景事件编号 [6]
    instruct_3(3,8,1,0,645,0,0,-2,-2,-2,-2,-2,-2);   --  3(3):修改事件定义:场景[有间>客栈]:场景事件编号 [8]
    instruct_0();   --  0(0)::空语句(清屏)
   
    -- 这里可以用狄云打了小兵后,踢了狄云,再拿连城诀,就可以不打戚长发
    if instruct_16(37,2,0) ==false then    --  16(10):队伍是否有[狄云]是则跳转到:Label0
        instruct_0();   --  0(0)::空语句(清屏)
        do return; end
    end    --:Label0

  --正线带狄云拿连城诀,到门口就会触发打戚长发战斗
  if JY.Person[37]["品德"] == 50 then
    instruct_37(1);   --  37(25):增加道德1
    instruct_1(233,37,0);   --  1(1):[狄云]说: 连城诀终于找到了,丁大哥*也可以安息了>。这是丁大哥*的遗物,就送给你吧。
    instruct_0();   --  0(0)::空语句(清屏)
    instruct_2(71,1);   --  2(2):得到物品[神照经][1]
    instruct_0();   --  0(0)::空语句(清屏)
    instruct_3(-2,21,0,0,0,0,8004,0,0,0,0,0,0);   --路过触发
    JY.Person[37]["品德"] = 51  --临时修改狄云的品德作为临时修改离队事件的判定
  end
```
8004.lua打戚长发,感慨人类的贪婪,到此连城诀线就完成了
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2024-7-6 21:36 | 显示全部楼层
至此连城诀线学习终于完成
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。

本版积分规则

小黑屋|手机版|铁血丹心

GMT+8, 2024-9-8 11:27

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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