骑马与砍杀中文站论坛

 找回密码
 注册(Register!)

QQ登录

只需一步,快速开始

搜索
12
返回列表 发新帖
楼主: Borr

ModuleSystem的坑爹事

[复制链接]
鲜花(41) 鸡蛋(0)
发表于 2016-5-17 19:37:58 | 显示全部楼层
本帖最后由 zhl199565 于 2016-5-17 20:24 编辑
Borr 发表于 2016-5-17 16:19
这里的重点是程序的可靠性。总不能写行代码,还老要考虑是不是有的时候不适用要打补丁。

至于数学问题 ...

计算机基本都是取余数设定都是被除数是负就带负的....
....首先计算机只有是和否,对数学运算只是一种人所设定的模拟...有兴趣可以详见通过原码反码补码如何用“是和否”来模拟加减乘除的效果....
所以这个这个根本不怪ms= = ,今天刚接触汇编发现现在的汇编就这么算的...
其实是我试图打开起砍的游戏硬核文件,而在这个过程便得知其语言是c/c++......visc++编译的...
目的是想找关于动作和音效的设定,别说找了,那些反汇编根本不是人看的....不过看头文件得知是先读取windows的各种dll来作为其基本的各项操作........所以无论是哪种方式编写的,这类最基础值的计算啊,还是什么计时器等等引用的是dll具体应该是其中的win32,而其他的dll用途也各不同...也就是说要改的不是ms............而是windows......(其实有的程序好像是自己做过把,就是额外自己定义了一种运算么= =,然后取名为除法在其程序内调用就行....).....




顺便说一下那个取平方根的.......我测试的时候设不同的定点乘数也好,结果每次输出的结果都是不同行的3个0!= =........
鲜花(1437) 鸡蛋(48)
发表于 2016-7-11 14:22:03 | 显示全部楼层
rubik 发表于 2016-2-14 23:11
又更新一坑。 "game_get_skill_modifier_for_troop"这个script的作用是让特定的兵种获得特定技能的额外加成 ...

刚刚来查坑,仔细看了下这个script,根据ms里面写的这个流程来看,似乎这个script在引擎的调用过程大概如此:
map free→循环获取party→循环队伍技能→获取对应的party队伍技能等级→获取单个troop的技能等级→调用此script检查是否有技能加成→输出最终技能等级参与相关计算


如果是这样的话,大概就是检测这本书获取技能等级的时候出现了类似死循环之类数据错误?
以上鄙陋之见,请多指教
鲜花(2231) 鸡蛋(8)
发表于 2016-7-11 23:12:36 | 显示全部楼层
蛋清 发表于 2016-7-11 14:22
刚刚来查坑,仔细看了下这个script,根据ms里面写的这个流程来看,似乎这个script在引擎的调用过程大概如 ...

类似的技能,比如侦查,向导就完全没有问题。
鲜花(1437) 鸡蛋(48)
发表于 2016-7-12 00:30:45 | 显示全部楼层
rubik 发表于 2016-7-11 23:12
类似的技能,比如侦查,向导就完全没有问题。

似乎脚印的数量会比起party的数量多很多?向导的话只是循环party,侦查最多也是双循环嵌套的party,但是脚印应该比较特殊吧
鲜花(2231) 鸡蛋(8)
发表于 2016-7-12 00:40:12 | 显示全部楼层
蛋清 发表于 2016-7-12 00:30
似乎脚印的数量会比起party的数量多很多?向导的话只是循环party,侦查最多也是双循环嵌套的party,但是脚 ...

可能是每个脚印都去判断跟踪的加成值了。 如果不加成,只是单纯的跟踪技能级别很高,则一点都不卡。
鲜花(161) 鸡蛋(66)
 楼主| 发表于 2016-8-23 14:13:15 | 显示全部楼层
新更一坑。

  neg 和 neq

的确,这两位长得很像,有时不注意就写串了。  这两个有时候可以互换的--- 但是 --- neq|opcode会改变opcode的编号,这个在编译的过程中是检查不出来的。然而运行中,会有红字跳出来说有个没有定义过的opcode。 是不是很纳闷没定义的opcode是怎么通过编译的? Ctrl+F找一下 neq| 也许就能发现问题所在。

鲜花鸡蛋

蛋清  在2016-8-23 14:27  送朵鲜花  并说:A.A
鲜花(161) 鸡蛋(66)
 楼主| 发表于 2017-2-12 01:37:39 | 显示全部楼层
再更一坑。

add_visitor_to_current_scene想来大家都挺常用的。当然在mt里边要先把相应的entry_point的属性设置好,要不然刷不出来,大家都是知道的。【当然这一点对新手来说已经相当得坑了】

但是,新的npc加进来以后,怎么获取刷出来的agent_id呢?reg0里边是木有的。

下边这个就是比较坑的事情了: 如果刚刚执行完add_visitor_to_current_scene,agent列表是没有刷新的。这个时候,无论是try_for_agents,还是用(try_for_range,":agent",0,1000)硬来,都是无法找到新加入的npc的agent_id。 这一点和spawn_agent非常不同。

所以,如果要对add_visitor_to_current_scene刷进来的人进行操作,最好是稍微延迟一下,等到下一帧【我一般会用另一个靠前的触发器,再延迟比如0.05秒再执行】再用try_for_agents,你就会惊喜地发现,这些npc们出现了。

这对编程上来说,还是挺麻烦的。本来一步做完的的事,非要分成两步。而且一次也许不是只要add_visitor_to_current_scene一个人,而是要加一批人进来,这时候彼此之间是不知道对方存在的,在一些判断上,需要注意规避。

评分

参与人数 1第纳尔 +20 互助 +1 收起 理由
蛋清 + 20 + 1 乐于助人!

查看全部评分

鲜花(4) 鸡蛋(0)
发表于 2017-4-15 17:09:32 | 显示全部楼层
关于第一个, py语言都是取模运算,貌似没有取余运算.只能通过先改符号再取模了...

不过运算结果都是没问题的:
如果a是正数,对负数求余,得到的就应该是负数.
当a是负数时,因为是取模运算, mod运算的商 取向负无穷(取余运算商向0靠近),所以余数也就是负数了.
鲜花(2231) 鸡蛋(8)
发表于 2017-4-22 16:51:03 | 显示全部楼层
本帖最后由 rubik 于 2017-4-22 17:23 编辑
蛋清 发表于 2016-4-25 18:00
再补个坑,跟汉化有关。
dialog里面上下标识为start:close_window的组会在编译时根据列表位置加上.x后缀方 ...

我来扩展一下,上下标识相同的时候,都会增加.x来相互区分,从而会发生这种情况。比如常见的start:lord_start,lord_give_order:lord_give_order_details_ask。 不过坑人最多的还是start:close_window,因为新对话,多是以start开头(用触发器来发起对话的不多),同时close_window也是所有对话的共同的结束标识。

另外新增一坑,也是关于对话的。凡是操作块里出现change_screen类的操作,后面的一句话不能是玩家说的,一旦是玩家说的,就会直接略过游戏自带的特殊界面,而直接显示玩家的对话。后面的一句话依然要求是对方说的,可以是新增的对话,也可以是已经存在的对话。 虽然对方连说两段话不符合一般的对话习惯,但是涉及到change_screen类的操作,必须这样做。

鲜花鸡蛋

蛋清  在2017-4-22 17:08  送朵鲜花  并说:学费
鲜花(830) 鸡蛋(15)
发表于 2017-8-25 17:11:52 | 显示全部楼层
联机GUID坑
骑砍制作估计是以为自己不会销量超过1000000,因此超过1000000的guid,如果直接拿到GUID然后对玩家ban 临时ban 踢出等操作将直接导致服务器崩溃。
解决办法可以参考admini Tools里面的代码

  1. #$adimi_tool_tk_until_ban_amount    kicks until ban
  2.   #$adimi_tool_tk_until_kick_amount   teamkills until kick

  3. ("adimi_tool_anti_tk_ban_check",
  4.   [
  5.     (store_script_param,":player",1),
  6.     (try_begin),
  7.      (player_is_active,":player",1),
  8.      (player_get_unique_id,":uid",":player"),
  9.      
  10.      (assign,":new_currently_tk_amount",-1),
  11.      (assign,":new_times_kicked_amount",-1),
  12.      (assign,":used_id",-1),
  13.      (try_begin),#Long ID or shorten id?
  14.       (lt,":uid",player_uid_limit),
  15.       (assign,":used_id",full),
  16.       (troop_get_slot,":currently_tk_amount",adimi_tool_tk_kick_warning_01,":uid"),
  17.       (troop_get_slot,":times_kicked_amount",adimi_tool_tk_kick_amount_01,":uid"),
  18.      (else_try),#If the Game ID is bigger than 1000000
  19.       (ge,":uid",player_uid_limit),
  20.       (store_sub,":uid",":uid",player_uid_limit_sub),
  21.       (assign,":used_id",shorten),
  22.       (troop_get_slot,":currently_tk_amount",adimi_tool_tk_kick_warning_02,":uid"),
  23.       (troop_get_slot,":times_kicked_amount",adimi_tool_tk_kick_amount_02,":uid"),
  24.      (try_end),
  25.      
  26.      (neq,":used_id",-1),#Stop here if the used_id is invalid
  27.      
  28.      (try_begin),# 1+ for the warning amount
  29.        (eq,":used_id",full),
  30.        (store_add,":new_currently_tk_amount",":currently_tk_amount",1),
  31.        (troop_set_slot,adimi_tool_tk_kick_warning_01,":uid",":new_currently_tk_amount"),
  32.        (assign,":result",warn),
  33.      (else_try),
  34.        (store_add,":new_currently_tk_amount",":currently_tk_amount",1),
  35.        (troop_set_slot,adimi_tool_tk_kick_warning_02,":uid",":new_currently_tk_amount"),
  36.        (assign,":result",warn),
  37.      (try_end),
  38.      
  39.      (try_begin),# 1+ for the kick amount + kick the player
  40.      (ge,":new_currently_tk_amount","$adimi_tool_tk_until_kick_amount"),
  41.      (try_begin),
  42.        (eq,":used_id",full),
  43.        (store_add,":new_times_kicked_amount",":times_kicked_amount",1),
  44.        (troop_set_slot,adimi_tool_tk_kick_amount_01,":uid",":new_times_kicked_amount"),
  45.      (else_try),
  46.        (store_add,":new_times_kicked_amount",":times_kicked_amount",1),
  47.        (troop_set_slot,adimi_tool_tk_kick_amount_02,":uid",":new_times_kicked_amount"),
  48.      (try_end),
  49.      (try_end),
  50.      
  51.      (try_begin),#Punishment
  52.        (ge,":new_currently_tk_amount","$adimi_tool_tk_until_kick_amount"),
  53.        (assign,":result",kick),
  54.      (try_end),
  55.      (try_begin),
  56.        (gt,":new_times_kicked_amount","$adimi_tool_tk_until_ban_amount"),#Ban.. 13:37 20.08.2013 fixed
  57.        (assign,":result",ban),
  58.      (try_end),
  59.      (call_script,"script_adimi_tool_anti_tk_punishment",":player",":used_id",":uid",":result"),
  60.     (try_end),
  61.   ]),
复制代码

鲜花(830) 鸡蛋(15)
发表于 2017-8-25 22:27:01 | 显示全部楼层
联机1.170改动ban人op坑

  1. ban_player                           = 466 # (ban_player, <player_id>, <value>, <player_id>), #set value = 1 for banning temporarily, assign 2nd player id as the administrator player id if banning is permanent
复制代码

第二player ID,如果是value=1的情况下,过去的代码是调用时候赋值为0,也可不赋值。
1.170之后,value=1 则第二个player id一旦给任何值都会导致服务器崩溃,不可赋值。
鲜花(161) 鸡蛋(66)
 楼主| 发表于 2018-3-7 23:50:13 | 显示全部楼层
新增几条。   
鲜花(85) 鸡蛋(1)
发表于 2018-4-24 15:37:32 | 显示全部楼层
学费学费
鲜花(830) 鸡蛋(15)
发表于 2018-6-2 09:44:53 | 显示全部楼层
联机player编号坑
如非必要,在引用player_no时候,请勿将其作为参数传值给其他函数,如果这样做,传的值会变成252。
当玩家是管理员时,传值才有可能不变(不可靠,在script里面会变,在mission template里面不会)。
解决办法,使用寄存器或者全局变量进行参数传值
您需要登录后才可以回帖 登录 | 注册(Register!)

本版积分规则

Archiver|手机版|小黑屋|骑马与砍杀中文站 ( 鄂ICP备07001403号 )

GMT+8, 2018-7-20 13:04 , Processed in 0.159708 second(s), 52 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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