骑马与砍杀中文站论坛

 找回密码
 注册(Register!)

QQ登录

只需一步,快速开始

搜索
购买CDKEY 衣谷三国
查看: 95|回复: 5

[源码与工具] 【狂人的知识】扩展兵种、物品等的数据

[复制链接]

48

主题

110

回帖

227

积分

见习骑士

Rank: 3

UID
3199602
第纳尔
1172
精华
0
互助
36
荣誉
0
贡献
1
魅力
227
注册时间
2020-9-4
鲜花(62) 鸡蛋(0)
发表于 昨天 21:56 | 显示全部楼层 |阅读模式
本帖最后由 奥杜因阿卡托什 于 2025-10-13 21:56 编辑

    本贴内容是与@huagao @战争傀儡阿格兰、偃靖共同讨论得出,背后原理详见花糕滴小知识——process入门动手篇(持续更新) - MOD制作技术区 - 骑马与砍杀中文站论坛 - Powered by Discuz!,本贴介绍其中一种应用。

     众所周知,兵种、物品这些数组,能储存什么信息都是固定的,比如兵种就只有ID、单复数名、flag等十几个位置能存储东西,第6号元素说是说reserved,但写了数据也获取不了,新增flag同样无法获取。随着mod内容发展,兵种、物品都有了各种各样新的信息需要存储,就职能使用slot。比如典中典之潘德的坐镇值,虽然是个每个兵种都有一个数据,但没法写在module_troop.py里,只能在脚本里搞长长一串troop set slot,即不好维护管理,新增删除时也多一道麻烦,新增数据只有一两种还好,多了可就比较麻烦了。
      虽然引擎所限,不用slot存数不行,但从逻辑上来讲,能不能把一些比较本征的slot和troop写在一起呢?比如把每个兵种和给它定义坐镇值的slot写一起,加的时候一起加,删的时候一起删,改的时候直接对应到人,多方便啊。可是我们都直到兵种没法像物品那样挂触发器,也写不了代码。不过,[难度4]MOD教程之Python语言在Module System里的简单应用 - MOD制作资料区 - 骑马与砍杀中文站论坛 - Powered by Discuz!这个贴给了我启发,能不能在troop、item等中添加新的数据,虽然没什么直接效用,但在编译的过程中,通过process把它们“神奇地”变成一行行troop set slot呢?答案是可以的。
     举个例子
  1.   ["watchman","Watchman","Watchmen",#眼线
  2.    tf_guarantee_boots|tf_guarantee_armor,
  3.    no_scene,reserved,fac_commoners,
  4.    [itm_shirt, itm_linen_tunic, itm_burlap_tunic, itm_leather_apron, itm_tabard, itm_butchering_knife, itm_dagger, itm_sword_medieval_b_small, itm_sword_medieval_c, itm_straw_hat, itm_head_wrappings, itm_headcloth, itm_felt_hat, itm_felt_hat_b, itm_wrapping_boots, itm_woolen_hose, itm_blue_hose, itm_ankle_boots, itm_pitch_fork, itm_military_fork, itm_battle_fork, itm_boar_spear, itm_simple_bow, itm_practice_arrows_2, itm_arrows],  
  5.    str_9|agi_7|int_5|cha_5|level(9), wp_one_handed (60) | wp_two_handed (60) | wp_polearm (60) | wp_archery (70) | wp_crossbow (60) | wp_throwing (70),
  6.    knows_ironflesh_1|knows_power_draw_1|knows_athletics_1|knows_horse_archery_1|knows_looting_1|knows_tracking_1|knows_pathfinding_1|knows_spotting_1|knows_first_aid_1|knows_trade_1,
  7.    mercenary_face_1, mercenary_face_2, "none",
  8.    tff_reconnaissance, #侦察
  9.   ],
复制代码
最后一行的   tff_reconnaissance, #侦察就是我新定义的兵种职能,是一个从未有过的数据位置。虽然本质上还是个slot,但直接在troop里填写、记录、查阅,远比去脚本里翻更舒服。


    下面给出代码
     首先,troop并没有给这个新数据留位置,你获取它,就会报错。因为我们要拓展数组,在process_troop.py里,把
  1.     if troop_len == 11:
  2.       troop[11:11] = [0, 0, 0, 0, 0]
  3.     elif troop_len == 12:
  4.       troop[12:12] = [0, 0, 0, 0]
  5.     elif troop_len == 13:
  6.       troop[13:13] = [0, 0, 0]
  7.     elif troop_len == 14:
  8.       troop[14:14] = [0, 0]
  9.     elif troop_len == 15:
  10.       troop[15:15] = [0]
复制代码
改成
  1.     if troop_len == 11:
  2.       troop[11:11] = [0, 0, 0, 0, 0, 0]
  3.     elif troop_len == 12:
  4.       troop[12:12] = [0, 0, 0, 0, 0]
  5.     elif troop_len == 13:
  6.       troop[13:13] = [0, 0, 0, 0]
  7.     elif troop_len == 14:
  8.       troop[14:14] = [0, 0, 0]
  9.     elif troop_len == 15:
  10.       troop[15:15] = [0, 0]
  11.     elif troop_len == 16:
  12.       troop[16:16] = [0]
复制代码
规律很简单,聪明人一眼就能看出。我这里是只加了一个新数据,加多少就这么加几层。

    然后在脚本里,最外一层[]的更外面,一无所有的荒原里,加入
  1. ##将存在troop里的兵种职能存进slot
  2. def set_troop_function():
  3.   troop_function = []
  4.   for i_troop in xrange(len(troops)):
  5.     troop_function.append((troop_set_slot, i_troop, slot_troop_function, troops[i_troop][16]))
  6.   return troop_function[:]
复制代码
16表示这个数据是从troop第16号位取的,也就是我填职能的位置。
这是一个py函数,比ms代码更高一层,它可以自动获取数据,帮你生成一条条(troop_set_slot, "cur_troop", slot_xxxxx, xxxxx),就避免了手输的麻烦。当然,自己用时这个slor_troop_fundtion记得改。

    最后,需要用一个脚本调用这个函数,把生成的(troop_set_slot, "cur_troop", slot_xxxxx, xxxxx),写进它里面,直接
  1. ("initialize_troop_function", set_troop_function()),
复制代码
即可,然后在game_start里call一下这个脚本,就行了。
  1.       (call_script, "script_initial_faction_data"),
复制代码

    对于txt和玩家而言,这么搞一把与直接写一大坨slot并无区别,然而对于ms深度作者而言,此功能对mod制作的帮助是不言而喻。希望大家多多举一反三,跑步进入新时代。


鲜花鸡蛋

偃靖  在昨天 22:01  送朵鲜花  并说:我非常同意你的观点,送朵鲜花鼓励一下

34

主题

247

回帖

199

积分

见习骑士

Rank: 3

UID
2462463
第纳尔
1617
精华
0
互助
23
荣誉
0
贡献
0
魅力
85
注册时间
2015-3-3
鲜花(64) 鸡蛋(0)
发表于 昨天 22:01 | 显示全部楼层
本帖最后由 战争傀儡阿格兰 于 2025-10-13 22:03 编辑

前排前排!原来还可以这样,又改了process,有不用增加额外的TXT数值

22

主题

175

回帖

194

积分

贵族[MOD作者]

Rank: 7Rank: 7Rank: 7

UID
3048044
第纳尔
2234
精华
0
互助
21
荣誉
3
贡献
20
魅力
516
注册时间
2018-12-15
鲜花(45) 鸡蛋(0)
发表于 昨天 22:40 | 显示全部楼层
奥内的手,好汉

19

主题

704

回帖

382

积分

见习骑士

Rank: 3

UID
3102512
第纳尔
2440
精华
0
互助
33
荣誉
0
贡献
0
魅力
84
注册时间
2019-9-6

骑砍中文站APP会员勋章战团正版勋章霸主正版勋章

鲜花(64) 鸡蛋(0)
发表于 5 小时前 | 显示全部楼层
我预言你马上就要编辑这个帖子
解解解解解解解解解解解解解解解解解解

48

主题

110

回帖

227

积分

见习骑士

Rank: 3

UID
3199602
第纳尔
1172
精华
0
互助
36
荣誉
0
贡献
1
魅力
227
注册时间
2020-9-4
鲜花(62) 鸡蛋(0)
 楼主| 发表于 5 小时前 | 显示全部楼层
huagao 发表于 2025-10-14 00:13
我预言你马上就要编辑这个帖子

预言错了,我直接回复。

48

主题

110

回帖

227

积分

见习骑士

Rank: 3

UID
3199602
第纳尔
1172
精华
0
互助
36
荣誉
0
贡献
1
魅力
227
注册时间
2020-9-4
鲜花(62) 鸡蛋(0)
 楼主| 发表于 5 小时前 | 显示全部楼层
本帖最后由 奥杜因阿卡托什 于 2025-10-14 00:42 编辑

    上面的办法,给物品、部队、部队模板、阵营这些用已经足够了,然而还有兵种却还有一个问题。加上之后,会发现兵种树顶端的兵,莫名多了一截升级。这就是因为升级树也是在troop之外添加的,和它冲突了。
因此,给troop添加新数组,需要让两位出来。比如
  1.   ["watchman","Watchman","Watchmen",#眼线
  2.    tf_guarantee_boots|tf_guarantee_armor,
  3.    no_scene,reserved,fac_commoners,
  4.    [itm_shirt, itm_linen_tunic, itm_burlap_tunic, itm_leather_apron, itm_tabard, itm_butchering_knife, itm_dagger, itm_sword_medieval_b_small, itm_sword_medieval_c, itm_straw_hat, itm_head_wrappings, itm_headcloth, itm_felt_hat, itm_felt_hat_b, itm_wrapping_boots, itm_woolen_hose, itm_blue_hose, itm_ankle_boots, itm_pitch_fork, itm_military_fork, itm_battle_fork, itm_boar_spear, itm_simple_bow, itm_practice_arrows_2, itm_arrows],  
  5.    str_9|agi_7|int_5|cha_5|level(9), wp_one_handed (60) | wp_two_handed (60) | wp_polearm (60) | wp_archery (70) | wp_crossbow (60) | wp_throwing (70),
  6.    knows_ironflesh_1|knows_power_draw_1|knows_athletics_1|knows_horse_archery_1|knows_looting_1|knows_tracking_1|knows_pathfinding_1|knows_spotting_1|knows_first_aid_1|knows_trade_1,
  7.    mercenary_face_1, mercenary_face_2, "none",
  8.    0, 0, tff_reconnaissance, #侦察
  9.   ],
复制代码
前面这两个0,0就是给升级树留的位。
    然而这还不够,升级树在写的时候并没有考虑会有人给它留位的情况,所以用的插值,会导致有升级的兵数组比没升级的兵多两位,填入的数位置也不同了。因此,找到header_troops.py,反到最下面def upgrade(troops,troop1_id,troop2_id):和def upgrade2(troops,troop1_id,troop2_id,troop3_id):,看到这两个升级树函数的最后一行,都用的是
  1.       cur_troop[14:14] = [troop2_no, 0]
复制代码
这个表示插值,会往14位后凭空插入两行。我们给它改成替换,用上预留的两位
  1.       cur_troop[14:14] = [troop2_no, 0]
复制代码
就行了。
    其余的差不多,记得因为多留了两位,process里需要18位,
  1. def save_troops():
  2.   file = open(export_dir + "troops.txt","w")
  3.   file.write("troopsfile version 2\n")
  4.   file.write("%d "%len(troops))
  5.   for troop in troops:
  6.     troop_len = len(troop)
  7.     if troop_len == 11:
  8.       troop[11:11] = [0, 0, 0, 0, 0, 0, 0, 0]
  9.     elif troop_len == 12:
  10.       troop[12:12] = [0, 0, 0, 0, 0, 0, 0]
  11.     elif troop_len == 13:
  12.       troop[13:13] = [0, 0, 0, 0, 0, 0]
  13.     elif troop_len == 14:
  14.       troop[14:14] = [0, 0, 0, 0, 0]
  15.     elif troop_len == 15:
  16.       troop[15:15] = [0, 0, 0, 0]
  17.     elif troop_len == 16:
  18.       troop[16:16] = [0, 0, 0]
  19.     elif troop_len == 17:
  20.       troop[17:17] = [0, 0]
  21.     elif troop_len == 18:
  22.       troop[18:18] = [0]
复制代码


而脚本里的def set_troop_function()只要写16位就行。不是18位也是由于那两个升级树。
  1. def set_troop_function():
  2.   troop_function = []
  3.   for i_troop in xrange(len(troops)):
  4.     troop_function.append((troop_set_slot, i_troop, slot_troop_function, troops[i_troop][16]))
  5.   return troop_function[:]
复制代码


您需要登录后才可以回帖 登录 | 注册(Register!)

本版积分规则

Archiver|手机版|小黑屋|骑马与砍杀中文站

GMT+8, 2025-10-14 05:46 , Processed in 0.100328 second(s), 24 queries , Gzip On, MemCached On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

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