本帖最后由 dsr1013 于 2010-12-30 12:38 编辑
(前面的半个月被BOSS叫去出差了。。然后悲剧的是,住的地方没有网。。我本人比较讨厌网吧,实在是没办法呢。但是,没有更新是我的罪过,实在是抱歉了。另外,圣诞这几天比较特殊。。同学聚会什么的就不提了,主要是PSP破 解了~我的板砖小P终于重见天日了。。然后是攻略《密室的祭品》。。为了能让大家第一时间知道这个帖子是否有更新,我在下面加了一个音乐播放器,每次更新会更换一首BGM。。鉴于我的音乐鉴赏水平不怎么样,如果不喜欢这个设定请提出啊~)
your browser does not support this tag
应佐罗兄的要求(背后的黑手是杨大没错。。),今天开始从官网转这么一个技术帖。由于文本量较大,而且还不断有人跟帖,所以先挖坑,以后慢慢填。
事实上,从刚开始看到这个帖发布时间的时候,我就在想,这么老的帖子现在转过来还有意义么(当时的M&B版本才0.731),翻译了一部分才知道,很有必要。原因之一,这个帖子不是一两个人写的教学帖,而是结合了大家思考的结晶;原因之二,这个帖子伴随骑砍一路发展到今天,其中讨论的种种问题都或多或少对游戏本身产生了重大影响,无论是历史帝考据帝还是技术帝,都可以在这里找到你们想要的东西。。
开始转帖之前,有几点需要说明:1、本人不保证翻译的正确性(尤其是专业术语,包括历史上某些MOD的名称及其作者);2、本人不会排版;3、本人不保证此坑有填满的一天;4、聊天、灌水等与讨论无关的楼层无视,不作翻译;5、代码段中#字符后面的语句全是注释内容,如果编译过程中出错,请检查一下是不是这里出了问题(主要看是不是多了或者漏了回车 )。
------------------------------------------------------------------------------------------------------------------------------------------------------
原帖地址:http://forums.taleworlds.com/index.php/topic,8652.0.html
-----------------------------------------------------------------------转帖开始-----------------------------------------------------------------------
顶楼 maw:
本主题仅供技术交流用,严禁灌水。
发布本主题主要是为方便大家提出有关实现骑马与砍杀相应功能的PY代码方面的问题。
请各位在分享代码的同时详细描述其作用或可实现的功能。同时,如果有感兴趣的MOD制作者PM各位申请代码的使用权,请予以回应。
好吧,下面转入正题。
再次申明,这个主题下不欢迎各类抱怨或者相互指责的内容,还请大家潜心投入到代码交流活动中来。
以下是我感兴趣的代码(对应0.731版骑砍):
1、有关大地图上征兵功能的PY代码,即和pt_字串有关的内容(玩家可以按自己的需要更改欲征募兵种的有关设定)
2、有关资助商队功能的PY代码,即由玩家出资建立一支商队,该商队不受玩家控制,且目的地也可以是随机的。当这支商队平安到达目的地(即没有受到攻击或者没被击溃的情况),玩家将取回自己的全额投资,并得到与商队移动距离有关的风险收益。
3、有关玩家队伍(main_party)中俘虏招募功能的PY代码,即玩家可在大地图上自由招募或释放俘虏。
4、将普通士兵“升级”为类似同伴的NPC状态的PY代码。
5、在大地图上扎营以使队伍中受伤士兵快速康复的PY代码。
6、实现对俘虏审讯及拷问功能的PY代码。
7、更简洁的招募酒馆中雇佣兵的PY代码(主要是希望能用更少的代码实现这一功能)。
最后,请大家牢记,这里只欢迎提出问题或分享代码。如果对回复内容有所疑问,请自行PM发言者,不要跟帖,谢谢。 - maw
(回复)3楼 dagorkan
如果谁能帮忙解决以下这些问题,那就真的帮了我大忙了(对应0.731版骑砍):
1、有关马匹战后自动回血和随时间流逝自动升级的PY代码。如果谁能做出这类代码,那应该就意味着其他物品也可以具有类似功能了吧。
2、可实现随游戏的进行,村庄内磨坊数量或大地图上的桥梁数会自动增加的功能的PY代码。同样,其他经济建筑也可以适用这类代码。
3、实现城镇内居民人数随玩家的举动增加或减少的功能的PY代码。
4、添加除原有技能之外的新“技能”的PY代码。这类新技能可在任务栏里查看说明和状态。
5、在角色创建页面增加成长机制,即可以通过定制角色的“职业生涯”来影响角色的初始状态。
6楼 Fujiwara(实现了日历功能)
我来发一下最近很受关注的日历脚本。
以下脚本原本是为0.711版编写的,由于0.730/0.731的代码形式并没有做太大变动,所以我个人认为此脚本兼容这两个版本。
太阳历(公历)纪年版:( 0.0 , 0 , ti_once, [], [(assign, "$day" , 1 ), (assign, "$month" , 7 ), (assign, "$year" , 1 )]),
( 0.0 , 24 , 0 , [(lt, "$day" , 31 )], [(val_add, "$day" , 1 )]),
( 0.0 , 0 , 0.0 , [(eq, "$day" , 31 ),(lt, "$month" , 13 )], [(val_add, "$month" , 1 ),(assign, "$day" , 1 )]),
( 0.0 , 0 , 0.0 , [(eq, "$month" , 13 )], [(val_add, "$year" , 1 ), (assign, "$month" , 1 )]),
太阴历纪年版:( 0.0 , 0 , ti_once, [], [(assign, "$day" , 1 ), (assign, "$month" , 7 ), (assign, "$year" , 1 )]),
( 0.0 , 24 , 0 , [(lt, "$day" , 29 )], [(val_add, "$day" , 1 )]),
( 0.0 , 0 , 0.0 , [(eq, "$day" , 29 ),(lt, "$month" , 14 )], [(val_add, "$month" , 1 ),(assign, "$day" , 1 )]),
( 0.0 , 0 , 0.0 , [(eq, "$month" , 14 )], [(val_add, "$year" , 1 ), (assign, "$month" , 1 )]),
以上代码中出现的$day、$month、$year参数的初始值均可按自己的喜好来设定。祝各位使用愉快~
我手上还有在和商人交易时强制将商品出售给“开放市场”而不是出售给商人本人的脚本,如果有谁需要的话,可以PM我索取。
9楼 Yoshiboy(貌似是实现了航海功能)
好吧,我会尝试解释一下我是如何区分陆地和海洋,并分别实现我的目的的。但是,我只会简要概述一下为何可以实现这些功能,如果你们想了解某些细节问题的话请结合我的源文件来自己领悟。源文件下载地址:http://www.warpmod.com/dev/YoshiBoy/pirates_v1.3_source.rar
那么,这层楼我就包下了,留个位置以后再来慢慢说明。(事实证明烂尾了啊。。)
19楼 Winter(实现了把俘虏杀掉做成风干肉的功能。。) [anyone, "prisoner_chat" , [], "What? You've already put me in chains, what more do you want to do?" , "prisoner_chat_2" ,[]],
[anyone|plyr, "prisoner_chat_2" , [], "Well, as it happens, you look rather tasty . . . Let's have a bite." , "prisoner_chat_3" ,[]],
[anyone|plyr, "prisoner_chat_2" , [], "Nothing." , "close_window" ,[]],
[anyone, "prisoner_chat_3" , [], "No! Nooooooooo!" , "prisoner_chat_4" ,
[
(store_conversation_troop,reg( 3 )),
(remove_troops_from_prisoners,reg( 3 ), 1 ),
(try_begin),
(store_free_inventory_capacity,reg( 4 ), "trp_player" ),
(ge,reg( 4 ), 1 ),
(troop_add_item, "trp_player" , "itm_dried_meat" ),
(end_try),
]],
[anyone|plyr, "prisoner_chat_4" , [], "There. Someone bring me my boning knife!" , "close_window" ,[]], [anyone, "prisoner_chat" , [], "你 又 想 做 什 么? 我 已 经 被 铁 链 限 制 住 了 自 由, 你 难 道 还 不 满 足 吗? " , "prisoner_chat_2" ,[]],
[anyone|plyr, "prisoner_chat_2" , [], "嘿 嘿, 你 看 起 来 好 像 很 好 吃 的 样 子…… 让 我 尝 一 口 吧, 就 一 口。 " , "prisoner_chat_3" ,[]],
[anyone|plyr, "prisoner_chat_2" , [], "没 什 么, 给 我 好 好 待 着。 " , "close_window" ,[]],
[anyone, "prisoner_chat_3" , [], "雅 蠛 蝶 啊! 别 过 来 呀! " , "prisoner_chat_4" ,
[
(store_conversation_troop,reg( 3 )),
(remove_troops_from_prisoners,reg( 3 ), 1 ),
(try_begin),
(store_free_inventory_capacity,reg( 4 ), "trp_player" ),
(ge,reg( 4 ), 1 ),
(troop_add_item, "trp_player" , "itm_dried_meat" ),
(end_try),
]],
[anyone|plyr, "prisoner_chat_4" , [], "嘿 咻。 来 人 啊, 把 我 的 剔 骨 刀 拿 过 来! " , "close_window" ,[]],
应建议区某些孩子的一再请求,现在把功能代码放出,有需要的骑友可以随意使用。
(Winter对杀人吃肉一事感到浪费。。)
20楼 Winter(实现了在场景中增加队中NPC的功能)
以下代码实现了判断马德尼或么么茶是否在队伍中,并在队中有此二人的情况下将他们加入到某个场景中的功能。(modify_visitors_at_site, "scn_<your scene here>" ),
(reset_visitors),
(try_begin),
(main_party_has_troop, "trp_borcha" ),
(set_visitor,<mission template entry number>, "trp_borcha" ),
(end_try),
(try_begin),
(main_party_has_troop, "trp_marnid" ),
(set_visitor,<different mission template entry number>, "trp_marnid" ),
(end_try), (Winter觉得自己活力四射ING。。)
21楼 Fujiwara(上述功能的升级版)
将队伍中所有NPC加入某个场景的代码:(modify_visitors_at_site, "scn_<your scene here>" ),
(reset_visitors),
(try_for_range,reg( 1 ),heroes_begin,heroes_end)),
(main_party_has_troop,reg( 1 )),
(assign,reg( 2 ),<inital mission template entry number>),
(set_visitor,reg( 2 ),reg( 1 )),
(val_add,reg( 2 ), 1 ),
(end_try), 感谢Winter提供的思路 XD
22楼 Winter
不客气,Fujiwara。但是需要指出的是,将自己做的MOD中的部分代码截取后直接粘贴出来可不是好的行为。比如这里的heroes_begin和heroes_end都是MOD中自己添加的变量,Native的MS(模组化系统,module system)里不存在这类定义。你在回帖中引用它们的时候应该说明这一点。
除了上述小问题,你的脚本写得不错。我爱死try_for_range的强大功能了~
(Winter觉得自己像个悲观主义者)
23楼 Janus(实现了统计队伍构成情况的功能)
我在这一楼将要放出的脚本是专为那些比普通玩家更愿意认真思索的程序员所准备的。以下脚本要实现的主要目标是列出某支部队的兵种构成,当然,还有兵种的数量。目前的脚本只能实现对非俘虏部队的统计功能,但我觉得稍加改进应该就可适用于所有类型的部队,包括俘虏。
如果你还没有意识到这段代码的重要性的话,那么我建议你不要再往下看了。
这次我想以一个示例性的脚本为例,将这个功能脚本形象地介绍给大家。该脚本的作用是在屏幕上显示玩家部队的构成情况。当然,玩家自然是知道自己的部队中有哪些兵种的,但是这个例子并非毫无意义,它很好地揭示了脚本的功用,并且可以视为开发这段脚本的其他用法的重要基石。
在这里我要特别感谢fisheye在如何使用更简洁的方式储存并逐个调用示例中某支部队的各类变量的问题上给予我的帮助。
首先,将下述代码添加到module_troops.py的部队列表的末尾处。要注意的是,这些代码必须添加到最后一支部队的后面,结尾处的括号之前。#do not place a troop past this point, it marks the end of the troops
[ "end_troops" , "end_troops" , "end_troops" ,tf_hero,no_scene,reserved,fac_commoners,[],def_attrib, 0 ,knows_common, 0 ], 然后,将以下字符串添加到module_strings.py文件中,这两行代码主要实现了示例脚本中的显示功能: ( "party_contains" , "The party '{s3}' contains {reg9} troop stacks:" ),
( "string3" , "{s3}" ), 再将下面的脚本代码添加到module_scripts.py中: ( "list_party_troops" , [ #这段脚本将对$party_to_check所指向的目标部队进行检查,并返回该部队中的兵种列表
(try_begin),[assign, "$party_stack_count" , 0 ],
(try_for_range,reg( 6 ), "trp_player" , "trp_end_troops" ),
[party_count_companions_of_type, reg( 7 ), "$party_to_check" , reg( 6 )], [gt, reg( 7 ), 0 ],
[troop_set_slot, "trp_end_troops" , "$party_stack_count" ,reg( 6 )],
[val_add, "$party_stack_count" , 1 ],
(end_try),
#在这里,“$party_stack_count”变量中保存的是“party_to_check”这支部队中的兵种数目;
#同时,这个变量也可以配合try_for_range循环操作使用,作为其结束循环时的函数值(这个值要比保存部队数据的寄存器中的数值大1),
#此外,“trp_end_troops”中的各个虚拟入口所指向的地址则储存了该部队中每种兵种的兵种ID。
(end_try),
]),
( "player_has_troops" , [ #这段脚本对list_party_troops的用法作了示范。这个函数将检测玩家的部队构成,并在屏幕上显示出来
(try_begin), [assign, "$party_to_check" , "p_main_party" ], #将“$party_to_check”的对象设置为玩家的部队,并将其作为list_party_troops的输入值
(call_script, "script_list_party_troops" ), #调用list_party_troops函数,以得到玩家部队中的兵种构成列表
[str_store_party_name, 3 , "$party_to_check" ],
(display_message, "str_party_contains" ), #在屏幕上标示出部队的名称和兵种的数量
(try_for_range, reg( 6 ), 0 , "$party_stack_count" ), #循环遍历部队中的所有的兵种。“$party_stack_count”中记录着兵种的数目,我们以这个参数作为遍历的结束参量
[troop_get_slot,reg( 7 ), "trp_end_troops" , reg( 6 )], [str_store_troop_name, 3 , reg( 7 )], (display_message, "str_string3" ),
#兵种的编号(ID)储存在虚拟的部队“trp_end_troops”中,从第0位(slot 0)开始排列。Reg(7)则对应当前的兵种编号,
#而兵种的名称则被存入临时字符串s(3),并显示在屏幕上
(end_try),
(end_try),
]), 最后,在游戏的任意一个操作块(operation block,可以是对话、菜单、触发器或者其他随便什么会被游戏主程序调用的段落)中添加如下代码来触发上述示例脚本:(call_script, "script_player_has_troops" ) 更新:对脚本进行了升级,现在已经不需要依赖reg(5)和reg(9)来取得必要的参数了,而是直接使用程序中定义过的变量$party_to_check以及$party_stack_count。
24楼 Winter
哈,Janus的计数手法和我在为《手工艺》MOD(craftmod)中增加新功能时使用的手法是一样的。现在我明白为什么你们会突发奇想地在骑砍的MS中增加寄存器读写功能了,这真是个聪明的想法。
然而,不幸的是,我为自己的脚本编写的代码还不能正常运行。至于为什么,其实是因为我的代码中采用了新版本骑砍(的MS)中新定义的一部分操作及命令。虽然暂时我的脚本还不能使用,但我可以向你们保证,等你们玩到《手工艺》的那一天,你们会喜欢上这个mod的。
(Winter刚刚吃了些匹鲁卡品,呜,药效发作啦!)
25楼 Fujiwara
不客气,Fujiwara。但是需要指出的是,将自己做的MOD中的部分代码截取后直接粘贴出来可不是好的行为。比如这里的heroes_begin和heroes_end都是MOD中自己添加的变量,Native的MS(模组化系统,module system)里不存在这类定义。你在回帖中引用它们的时候应该说明这一点。
说得很对,感谢Winter为我指出这个问题。
除了上述小问题,你的脚本写得不错。我爱死try_for_range的强大功能了~
如果没有try_for_range这条语句的话,对我来说,这就像是人离开了氧气、鱼儿离开了水那样痛苦。 XD
Janus,你用trp_end_troops这个“假”部队来存储兵种信息,这个想法实在是太聪明了。我之前也用过类似的手法,比如创造一个虚拟场景,来储存用以实现场景内物体随季节、城镇的方位及城镇的大小来自动变化所需要的各类数据。你的代码很不错,十分值得我借鉴。
26楼 Winter
Janus,你用trp_end_troops这个“假”部队来存储兵种信息,这个想法实在是太聪明了。我之前也用过类似的手法,比如创造一个虚拟场景,来储存用以实现场景内物体随季节、城镇的方位及城镇的大小来自动变化所需要的各类数据。你的代码很不错,十分值得我借鉴。
看过了我的编程手法后,再来赞叹也不迟哦~
我把我所有的新构思都集成到了我的MOD里,用来实现某个令人震惊的新功能。请大家关注下即将推出的新版本《手工艺》MOD——我在这个版本中使用了一些过渡性的代码以加快更新的速度。此外,我还需要编辑一下场景,添加一些任务任务模板代码,这些都搞定之后,我的MOD就正式进入公开测试的收尾阶段了。
(Winter向大家频频致意~)