actboy168 actboy168
关注数: 4 粉丝数: 840 发帖数: 24,296 关注贴吧数: 22
【科普】YDWE自定义值的原理 YDWE的自定义值的本质是哈希表(在120下是GC,不过120应该快灭绝了吧),相信很多人都知道。但他又不单单是哈希表这么简单。 先看一个例子 local unit u = GetTriggerUnit() call YDUserDataSet(unit, u, "力量", integer, 100) 这是在转为自定义代码里看到的效果,但当你实际保存之后,你会发现代码会变成这样 call SaveInteger(YDHT, GetHandleId(u), 0x30FA192C, 100) 如果用哈希表写,应该怎样写呢,大概应该有三种写法吧 call SaveInteger(YDHT, GetHandleId(u), StringHash("力量"), 100) call SaveInteger(YDHT, GetHandleId(u), 1, 100) call SaveInteger(YDHT, GetHandleId(u), '+str', 100) 第一种写法,StringHash有运行时的性能消耗,而且还会让字符串池增加了一个字符串,是性能很差的写法。 第二种写法,性能和自定义值相同,但是可读性较差,你只能通过注释或者自己的记忆来记住这是什么东西。 第三种写法,性能和自定义值相同,可读性也不错,在你英文还行的前提下,不过限定4个英文字母,所以表达能力有限。 总的来说,YDWE的自定义值和用Jass裸写哈希表比,性能一致或更好,可读性应该是最好的。 不过YDWE自定义值并非是为写Jass的人准备的,如果是用Jass来写YDWE自定义值,还可以简化一些。 比如描述u的类型unit,实则只需要关心u是不是handle(因为所有的handle都是用GetHandleId来转为整数),所以是可以省略的。 YDWE自定义值的缺点? YDWE自定义值的局限性在于第三个参数(也就是“力量”)必须是常量,这样YDWE才可以在编译时简化掉字符串。加这个限制也正是为了性能的考虑。所以我也正在考虑加一个变量版的自定义值,这样功能就和哈希表完全一致了,同时使用变量版的自定义值,你就需要考虑上面三种哈希表写法所面临的问题。
重制版不过是1.31收费补丁 一个有意思的细节是,这次的重制英文名是reforged,一般重制的英文应该是remastered(比如星际一重制就是这个)。为了方便描述,下面称即将推出的“重制版”为高清版,重制依然为通常的含义。 blz有提到高清版只是替换了高清模型,并没有修改引擎,比如还可以和非高清版联机。非高清版编辑器做出来的图也可以在高清版上使用。但不知道在高清版出来之后,非高清版就会不会获得更新,从可以联机来看,应该是会获得更新的。(也许会持续一段时间?)对于对战玩家,这挺不错,但对RPG玩家就坑爹了。(RPG玩家一贯三等公民)首先但看高清版,自带的模型是高清了,但跟自定义模型又没有半毛钱关系。如果你的图全用自定义模型,那高清版和非高清版没有任何区别。如果你的图自定义模型和自带模型皆有,那么风格差别极大的模型混在一起,看起来一定十分诡异。总之用了自定义模型的图,高清版并没有那么美好。 也许你可以重新做一套和高清版风格匹配的模型,但是也存在两个问题。首先,高清版的模型制作成本和制作门槛一定大幅度上升,况且因为引擎根本没换,高清版能做的事情,现在就能做,那么为什么不现在做呢,因为不需要不值得。其次,请记住高清版是可以和非高清版一起玩的,那么你的图是打算支持两个版本吗?blz的模型是在游戏里的,所以高清版看到的是高清模型,非高清版看到的是非高清模型;但是自定义地图如果用了高清自定义模型,非高清版看起来就会很奇怪,反之亦然。 另一个细节是,在英文版的官网上只有一个“预售”的按钮,而中文版上是“立刻预约”+“了解官方对战平台”两个按钮。预售就是买游戏,预约只是留个手机号(以便给你推送网易游戏的广告),而网易对战平台压根没出现任何与之相关的消息。所以我只能推测,高清版依然和之前一样,中文玩家无法购买正版,只能使用网易提供的盗版。不知道在英文官网购买的版本会不会提供中文,已经还会不会锁区。 不过官网有提到会假如现代BN的特性,现代BN应该指的就是BN2.0吧。英文版应该会登录BN2.0,这应该没什么疑问,但中文版会如何处理?因为网易对战平台和BN2.0本质是冲突的。首先先考虑英文版,BN2.0提供的IM系统,语音聊天之类的接入很简单,应该没问题。但BN2.0依然缺乏了匹配、房间、积分等概念,所以英文版可能会沿用非高清版内置BN的东西。这对英文版来说这并不是什么好消息,因为魔兽的内置BN从现在的角度看实则是太垃圾了。有没有可能内置BN大幅度重做?我觉得不太可能,毕竟你还要跟非高清版联机。而中文版,匹配、房间、积分这些东西在网易对战平台里已经解决了,反倒不会成为问题;只是加入“现代BN功能”这句话只是在骗人了。 最后说说兼容非高清版编辑器的事。自从blz恢复更新以来,每个版本都在加入破坏性改动,也许高清版不会像重制那样完全不兼容旧版,但他顶多就像1.30对1.29,1.29对1.28,1.28对1.27那样,你想直接升级?不存在的。而且只要BLZ对RPG的态度不变,这种版本的兼容性就会一直持续下去。顺便我说一个从宣传片看到的不兼容的地方,高清版把技能UI改了,从三行变成两行,我们都知道,技能位置是按坐标来指定的,还有一些非常tricky的不按坐标的做法,那么这些东西会在新UI里变成什么样,真的能兼容? 总的来说,我没看到任何对RPG利好的东西,暴雪依然是那个眼里只有对战的暴雪。不过也不完全是负面的,一是暴雪这次收到钱了,后续也许会投入更多的资源进去(就算全投到对战里,RPG说不定也能舔到点残羹剩饭);二是做个高清版也可以吸引一波新人;三是幸好不是出了个网易出品的魔兽3手游。
【科普+预告】泄漏检测 YDWE已经历经了三个版本的泄漏检测 第一个版本就是搬运了老外的jass库,原理是利用vjass的钩子来钩一些常用的函数。不过问题很多,vjass的钩子本身就很多毛病,加上原理上来说这个库只会告诉你当前已经存在哪些handle,实际上并不能告诉你哪些handle是泄漏了,哪些是正常的handle。 第二个版本是我写的。原理和老外的相同,只是从vjass的钩子改成理论YDWE的预处理来实现,并且利用YDWE的代码生成让泄漏检测库获得了获取当前触发器的触发器名的功能,以便可以更好地定位泄漏的handle的位置。不过由于原理相同,和第一个版本比只是bug变少了,其他问题依然存在。 第三个版本就是现在YDWE里的泄漏检测插件,泄漏检测插件包含两个功能,一个是第二个版本的C++移植版,使用C++做钩子速度上比Jass快了很多,但原理相同所以遇到的问题也相同;另一个是一个遍历所有handle以及列出它们的信息的功能,通过手动分析,可以解决大多数的泄漏问题。这种方式我认为是最有效和合理的泄漏检测,不过当初加这个,只是因为自用,对我而言,手动分析就足够了,但可能大多数人并搞不懂这个功能。 最近我对这个新的泄漏检测方式做了大量的优化,以便让更多的人可以使用它。同时旧的方式应该也可以退役了。那么我就来简单的说下原理。 魔兽的handle(准确地说是agent)都是由引用计数来管理,当引用计数变为0时,handle就会被释放。假如一个handle的引用计数永远也无法变为0,那么我们就可以认为这个handle已经(有)泄漏了,这就是这个泄漏检测的原理。 为了找到引用计数永远也无法变为0的handle,我们得先找到引用这个handle的地方有几处,每有一处则意味着当此处的引用被释放后,引用计数就会减一,所以问题变成了找到 “引用计数大于引用handle的数量”的handle。 对于魔兽而言,引用handle的有三种对象、变量和哈希表。所以你会看到这样的报告 handle: 0x0010005A 引用: 5 类型: trigger 对象: +trg 引用它的变量: | gg_trg_____________u | TEST!trg 引用它的哈希表: | handle:0x00100048 [1][1] 这个handle有1个对象、2个变量、1个哈希表引用它,但引用计数是5,所以这个handle就有泄漏。 不过这里还有一种情况,假如0x00100048这个哈希表已经对象泄漏(也就是没有任何变量或哈希表引用者它),则意味着你永远无法把0x00100048里的东西释放掉,这实则也是泄漏了,即使这个handle的引用计数正确。暂时我认为这种情况还是你自己手动分析比较好。 以上这种被称为handle泄漏,handle泄漏是写Jass的人最容易犯的错误,因为魔兽有个坑爹的bug,函数参数的handle不会自己释放引用。即使是暴雪自己写的代码(blizzard.j)也包含着大量的泄漏,就是因为这个原因。不过YDWE不会去用原版的blizzard.j,所以写T的人很少会遇到这个问题,但写J就很常见了。 还有一种泄漏是对象泄漏,如果一个handle没有被任何变量和哈希表引用,但被对象引用,这个就是对象泄漏。但并不是所有的对象泄漏都是泄漏,有些对象泄漏是正常的。对象泄漏的实际含义是,我们无法通过变量或者哈希表的手段来获取这个对象。但是有可能我们还有别的手段获取它,比如1.20时代的gamecache,还有像单位我们虽然没有变量记录者它,但我们依然可以用选取的方式来找到这个单位,在这种情况下,它并不算泄漏。 最后一种情况是,泄漏但实则无所谓的。例如player,在魔兽里player总是固定的16个,这16个handle引用或者不引用,其实都是无所谓的。
一个新的想法,自定义事件 之前做了一个逆天运行触发器,不知道有多少人在用。自定义事件可以说是运行触发升级版。 先看运行触发器(摘自ydwe的演示) pick 事件 单位 - 任意单位 获得物品 条件 动作 [逆天] - 运行 display <预设>, 无视条件 参数 [逆天] - [单位] loc_单位 = (触发单位) [逆天] - [物品] loc_物品 = (**作物品) display 事件 条件 动作 游戏 - 对 玩家1(红色) 在屏幕位移(0.00,0.00)处显示文本: (((loc_单位) 的名字) + 拾取了 + ((loc_物品) 的名字)) 运行触发器是1:1,而自定义事件则是1:n,也就是说你可以写多个display的触发器,只有它们用相同的字符串关联起来。 pick 事件 单位 - 任意单位 获得物品 条件 动作 [逆天] - 发布 获得物品 事件, 无视条件 参数 [逆天] - [单位] loc_单位 = (触发单位) [逆天] - [物品] loc_物品 = (**作物品) display1 事件 逆天 - 获得物品 事件 条件 动作 游戏 - 对 玩家1(红色) 在屏幕位移(0.00,0.00)处显示文本: (((loc_单位) 的名字) + 拾取了 + ((loc_物品) 的名字)) display2 事件 逆天 - 获得物品 事件 条件 动作 游戏 - 对 玩家1(红色) 在屏幕位移(0.00,0.00)处显示文本: (((loc_单位) 的名字) + 拾取了 + ((loc_物品) 的名字)) 一些尚未完善的细节: 1. 参数 可以让数据从pick触发器传递到display触发器,但没有display触发器没有办法把数据传给pick触发器。(逆天运行触发器也有同样问题) 2. 动态触发器(逆天触发器)使用自定义事件时,需要回收资源。(不建议在动态触发器中用自定义事件,不过也许也应该提供一个回收自定义事件的UI) 3. 考虑到会被白嫖,所以我就是随便说说
使用YDWE的人越来越多,但这并不是我想要的 今天看了下YDWE的同时在线人数,已经接近700人了,相比一年前还有所增长。然而放眼整个魔兽社区,情况则正好相反,论坛基本上已经死光,贴吧的活跃度也每况愈下。种种迹象看起来,魔兽社区正在萎缩。为什么会有截然不同的两种情况呢。 过去我曾经说过,用WE的有两种人,一种是做地图的人,一种是玩编辑器的人。而我认为现在可以分为三种人,玩编辑的人、为爱做图的人、为钱做图的人。所以很明显了,现在前两种人已经大幅度减少,第三种人正在急剧增加。 过去的社区基本都是靠前两种尤其是第一种人在支撑。而现在大家都太功利了,没人愿意分享自己的东西,因为别人可能是你的商业竞争对手亦或者是你的潜在客户。所以我觉得魔兽社区已经差不多gameover了,就算是还有点人的贴吧,也就是有钱钱纠纷时会热闹一下。然而这并没有任何意义。 过去的几十年,人类科技树发展最快的计算机硬件和软件。十年前的汽车和现在的汽车几乎你找不出有什么区别,而十年前你甚至还在用翻盖手机,而现在的手机已经完全不是一个物种了。触屏手机软件更是在这十年内从无到有,成为每个人生活种不可或缺的一部分。计算机技术的高速发展,我认为很大一部分功劳归功于开源文化的盛行。计算机技术的每个分支的最顶级或者次顶级都有开源的实现,几乎不存在所谓的独家秘方。即使闭源的项目,内部也一定用了大量的开源技术作为基石。很多顶级公司也认为开源自己的技术会给自己带来更高的收益,从而形成良性的循环。计算机行业发展到现在的高度,我已经很难想象没有开源会是什么样子,也许会退到十年前,甚至更久之前。 很早以前,我也曾经希望魔兽社区也可以效仿计算机技术,借助开源的力量来高速发展。所以我一直都认为地图加密技术是对社区发展有害的东西,不过幸好魔兽地图是无法真正意义的加密的。当我听到暴雪打算让银河编辑器可以真正的加密地图时,我觉得暴雪它想错,而且是严重的错误。不过一切终究也只是想想,一个人的力量很难改变什么。即使在计算机行业里,开源盛行也只是在国外,并不包括中国。
YDWE泄漏检测 在适当的地方添加这一行即可,call GetLocalizedHotkey("yd_leak_monitor::create_report")。或者你可以看YDWE附带的演示。 所谓的泄漏检测,实际上只是告诉你当前存活的handle有哪些,有些可能是正常的handle,有些则是真的泄漏了,这需要你自行分辨。 我只做了6种handle的检测,大多数的临时handle都是这6种类型,应该够用了。包括点(location),特效(effect),单位组(group),不规则区域(region),矩形区域(rect),玩家组(force)。 生成的报告如下: 引用:一个handle引用数为0就会被释放,换句话说handle之所以没被释放就是因为引用数不为0。一般来说每存放在一个全局变量、局部变量中引用就会+1,局部变量最后没有set null会导致引用永久+1(大多数泄漏的来源),还有各种魔兽坑爹的潜规则。 创建位置:只有上述6种handle会有创建位置,方便你定位泄漏的根源。 类型:这个是魔兽内部的类型名,我没转换为jass里对应的类型名。 handle:和GetHandleId获得的值一致 引用它的全局变量:一般来说被全局变量引用的handle我们不认为它是泄漏。 --------------------------------------- 泄漏检测详细报告 --------------------------------------- 点(location): 0 特效(effect): 0 单位组(group): 3 不规则区域(region): 0 矩形区域(rect): 2 玩家组(force): 17 --------------------------------------- 当前handle总数:93 --------------------------------------- handle: 0x00100001 引用: 1 类型: +tmr 引用它的全局变量: | bj_volumeGroupsTimer handle: 0x00100002 引用: 1 类型: +tmr 引用它的全局变量: | bj_queuedExecTimeoutTimer handle: 0x00100003 引用: 1 类型: +grp 创建位置: <init>, 1912 引用它的全局变量: | bj_suspendDecayFleshGroup handle: 0x00100004 引用: 1 类型: +grp 创建位置: <init>, 1915 引用它的全局变量: | bj_suspendDecayBoneGroup handle: 0x00100005 引用: 1 类型: +tmr 引用它的全局变量: | bj_delayedSuspendDecayTimer handle: 0x00100006 引用: 1 类型: +grp 创建位置: <init>, 1950 引用它的全局变量: | bj_lastCreatedGroup handle: 0x00100007 引用: 1 类型: +tmr 引用它的全局变量: | bj_lastStartedTimer handle: 0x00100008 引用: 5 类型: +ply handle: 0x00100009 引用: 2 类型: +snd 引用它的全局变量: | bj_dayAmbientSound handle: 0x0010000A 引用: 2 类型: +snd 引用它的全局变量: | bj_nightAmbientSound handle: 0x0010000B 引用: 2 类型: +ply handle: 0x0010000C 引用: 1 类型: +ply handle: 0x0010000D 引用: 1 类型: +ply handle: 0x0010000E 引用: 1 类型: +ply handle: 0x0010000F 引用: 1 类型: +ply handle: 0x00100010 引用: 1 类型: +ply handle: 0x00100011 引用: 1 类型: +ply handle: 0x00100012 引用: 1 类型: +ply handle: 0x00100013 引用: 1 类型: +ply handle: 0x00100014 引用: 1 类型: +ply handle: 0x00100015 引用: 1 类型: +ply handle: 0x00100016 引用: 1 类型: +ply handle: 0x00100017 引用: 2 类型: +ply handle: 0x00100018 引用: 2 类型: +flt 引用它的全局变量: | filterIssueHauntOrderAtLocBJ handle: 0x00100019 引用: 2 类型: +flt 引用它的全局变量: | filterEnumDestructablesInCircleBJ handle: 0x0010001A 引用: 2 类型: +flt 引用它的全局变量: | filterGetUnitsInRectOfPlayer handle: 0x0010001B 引用: 2 类型: +flt 引用它的全局变量: | filterGetUnitsOfTypeIdAll handle: 0x0010001C 引用: 2 类型: +flt 引用它的全局变量: | filterGetUnitsOfPlayerAndTypeId handle: 0x0010001D 引用: 2 类型: +flt 引用它的全局变量: | filterMeleeTrainedUnitIsHeroBJ handle: 0x0010001E 引用: 2 类型: +flt 引用它的全局变量: | filterLivingPlayerUnitsOfTypeId handle: 0x0010001F 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[0] handle: 0x00100020 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[1] handle: 0x00100021 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[2] handle: 0x00100022 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[3] handle: 0x00100023 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[4] handle: 0x00100024 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[5] handle: 0x00100025 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[6] handle: 0x00100026 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[7] handle: 0x00100027 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[8] handle: 0x00100028 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[9] handle: 0x00100029 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[10] handle: 0x0010002A 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[11] handle: 0x0010002B 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[12] handle: 0x0010002C 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[13] handle: 0x0010002D 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[14] handle: 0x0010002E 引用: 1 类型: +ply handle: 0x0010002F 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 43 引用它的全局变量: | bj_FORCE_PLAYER[15] handle: 0x00100030 引用: 1 类型: +ply handle: 0x00100031 引用: 2 类型: +frc 创建位置: InitBlizzardGlobals, 62 引用它的全局变量: | bj_FORCE_ALL_PLAYERS handle: 0x00100032 引用: 2 类型: +snd 引用它的全局变量: | bj_rescueSound handle: 0x00100033 引用: 2 类型: +snd 引用它的全局变量: | bj_questDiscoveredSound handle: 0x00100034 引用: 2 类型: +snd 引用它的全局变量: | bj_questUpdatedSound handle: 0x00100035 引用: 2 类型: +snd 引用它的全局变量: | bj_questCompletedSound handle: 0x00100036 引用: 2 类型: +snd 引用它的全局变量: | bj_questFailedSound handle: 0x00100037 引用: 2 类型: +snd 引用它的全局变量: | bj_questHintSound handle: 0x00100038 引用: 2 类型: +snd 引用它的全局变量: | bj_questSecretSound handle: 0x00100039 引用: 2 类型: +snd 引用它的全局变量: | bj_questItemAcquiredSound handle: 0x0010003A 引用: 2 类型: +snd 引用它的全局变量: | bj_questWarningSound handle: 0x0010003B 引用: 2 类型: +snd 引用它的全局变量: | bj_victoryDialogSound handle: 0x0010003C 引用: 2 类型: +snd 引用它的全局变量: | bj_defeatDialogSound handle: 0x0010003D 引用: 2 类型: +trg 引用它的全局变量: | bj_delayedSuspendDecayTrig handle: 0x0010003E 引用: 1 类型: tmet handle: 0x0010003F 引用: 1 类型: +tac handle: 0x00100040 引用: 2 类型: +trg 引用它的全局变量: | bj_queuedExecTimeout handle: 0x00100041 引用: 1 类型: tmet handle: 0x00100042 引用: 1 类型: +tac handle: 0x00100043 引用: 2 类型: +snd 引用它的全局变量: | bj_dawnSound handle: 0x00100044 引用: 2 类型: +snd 引用它的全局变量: | bj_duskSound handle: 0x00100045 引用: 2 类型: +trg 引用它的全局变量: | bj_dncSoundsDawn handle: 0x00100046 引用: 1 类型: gfvt handle: 0x00100047 引用: 1 类型: +tac handle: 0x00100048 引用: 2 类型: +trg 引用它的全局变量: | bj_dncSoundsDusk handle: 0x00100049 引用: 1 类型: gfvt handle: 0x0010004A 引用: 1 类型: +tac handle: 0x0010004B 引用: 2 类型: +trg 引用它的全局变量: | bj_dncSoundsDay handle: 0x0010004C 引用: 1 类型: gfvt handle: 0x0010004D 引用: 1 类型: gfvt handle: 0x0010004E 引用: 1 类型: +tac handle: 0x0010004F 引用: 2 类型: +trg 引用它的全局变量: | bj_dncSoundsNight handle: 0x00100050 引用: 1 类型: gfvt handle: 0x00100051 引用: 1 类型: gfvt handle: 0x00100052 引用: 1 类型: +tac handle: 0x00100053 引用: 2 类型: +rct 创建位置: InitMapRects, 33 引用它的全局变量: | bj_mapInitialPlayableArea handle: 0x00100054 引用: 2 类型: +rct 创建位置: GetCurrentCameraBoundsMapRectBJ, 9 引用它的全局变量: | bj_mapInitialCameraBounds handle: 0x00100055 引用: 2 类型: +tmr 引用它的全局变量: | bj_stockUpdateTimer handle: 0x00100056 引用: 2 类型: +trg 引用它的全局变量: | bj_stockItemPurchased handle: 0x00100057 引用: 1 类型: pevt handle: 0x00100058 引用: 1 类型: +tac handle: 0x00100059 引用: 1 引用它的全局变量: | bj_gameStartedTimer handle: 0x0010005A 引用: 5 类型: +trg 引用它的全局变量: | gg_trg_____________u handle: 0x0010005B 引用: 4 类型: pevt handle: 0x0010005C 引用: 1 类型: +tac handle: 0x0010005D 引用: 4 类型: pecd
YDWE三年回顾 正好是1.29~1.32四个版本。 [New] Lua引擎,新增键盘鼠标消息库 [New] Lua引擎,新增发布本地命令库 [New] Lua引擎,新增大数库 [New] Lua引擎,新增日志库 [New] Lua引擎,新增jass.debug库 [New] Lua引擎,新增jass.ai库,包含了所有的native ai函数(但不保证一定可用,就如在jass里一样) [New] Lua引擎,jass.debug库新增函数current_pos,可以获取当前Jass的运行的位置 [New] Lua引擎,jass.hook库现在可以访问到hook函数 [New] Lua引擎,jass.slk库增加misc表 [New] Lua引擎,jass.slk库重写,修正了大量的错误并且现在能返回正确的类型。 [New] Lua引擎,jass.japi库,新增添加japi函数的功能。 [New] Lua引擎,支持技能的鼠标事件 [New] Lua引擎,支持读取技能按钮数据 [New] Lua引擎,支持中文路径 [New] Lua引擎,从5.2.1升级到5.3.4 [New] Lua引擎,现在支持使用vscode进行调试 [New] Lua引擎,现在会默认加载入口文件script/war3map.lua,当使用新的加载方式时,旧的加载方式(使用Cheat)将不可用。 [New] Lua引擎,支持在config里使用 [New] Lua引擎,支持utf8库和io库的部分函数 [New] Lua引擎,部分标准库api支持,package.searchers/package.preload/package.searchpath。 [New] Lua引擎,增加handle的引用api [New] Lua引擎,现在支持支持任意table和userdata的排序次序(不再是随机) [New] 新增Japi读写Buff数据 [New] 新增Japi读写Item数据 [New] 新的Japi,图标融合 [New] 新的Japi,单位晕眩 [New] 新的Japi,单位变身 [New] Japi支持读写开关技能的图标 [New] Japi现在可以自动帮你计算暗图标 [New] 读写物品字符串支持提示和说明。 [New] 支持打开和保存为Lni地图 [New] 支持打开未知的UI的地图(但无法正确保存)。 [New] 测试地图时,支持自动将地图slk化 [New] 局域网测试增加多人模式 [New] 局域网测试支持 [New] 去掉地图大小限制 [New] 新增自动适应当前分辨率的选项(和固定窗口比例互斥) [New] 全新的pjass语法检查器,支持更多的语法错误检查。 [New] 重写了`新建物体指定ID`的UI [New] 新增智能施法演示 [New] 编译地图现在总是使用w3x2lni来打包地图 [New] 物编读取重写,并增加物编写入功能 [New] 使用stormlib替换JassHelper中sfmpq,提高读写地图的成功率 [New] 补丁包支持加载storm.dll [New] UI文件内置多语言的支持。 [New] 新的逆天UI,运行触发器 [New] 新的逆天UI,局部变量数组 [New] 新的逆天UI,收纳盒 [New] 新的UI,'发布中介命令'现在支持用技能ID来发布命令 [New] 新的UI,现在命令ID可以转换为无目标、单位目标、点目标命令等 [New] 新的UI,增加了一个昏迷的命令ID [New] 新的UI,'算术运算Lv3'和'连接字符串 Lv3' [New] 新增jass.debug的演示 [New] 新增创建计时器窗口的UI [New] 新增11平台的RPG积分UI [New] 新增11平台的RPG计费UI [New] 重写逆天UI的生成代码,现在局部变量和其他数据在不同的数据表中 [New] 替换了WE读取物编数据的流程,以解决War3和WE读取物编数据的不一致行为 [New] 第一次启动时会默认关闭刷子表和不创建新地图 [New] 自动转换不正确的物编数据类型 [New] "能提高护甲的物品"的防御奖励的类型从整数改为实数 [New] 增加了五个隐藏buff在编辑器的显示,分别是Bsta、Bdbb、BIpb、BIpd、Btlf [New] UTF8编码的中文路径文件不再会在保存后被丢弃 [New] 物品分类增加一个“混杂*真”,以解决原版WE“混杂”分类有错误的bug
新企划 新的编译为Jass的语言 没什么别的意思就是做来玩玩而已,目前只是简单的构思阶段,做不做甚至都还不确定。以下是目前构思的特性 1. 类Lua语法。因为Lua比较熟悉,虽然也有部分语法不喜欢,但大部分都还行。 -- if if a == 1 then end -- loop for i = 1, 3 do end while a == 1 do end 2. 静态类型。因为Jass本身就是静态类型的。语法为 local x:int = 1 local y:string = "2" local z:string = 3.0 -- 语法错误 function foo(a:int, b:int):string return I2S(a + b) end 3. 类型推导。在类型可以推断出来的地方,类型定义可以省略,例如下面都是合法的语法。 local x = 1 -- x的类型是int local y = "2" -- y的类型是string local z = 3.0 -- z的类型是float local w = y -- w的类型是string 4. 数组 local a:int[] for i = 1, 3 do a[i] = i end 5. 两种定义函数的方法。 function foo(a:int, b:int):string return I2S(a + b) end foo(a:int, b:int):string => return I2S(a + b) end 6. 匿名函数。 -- 由于类型推导,匿名函数定义里的类型都可以省略 TimerStart(t, 1.0, true, function() DoNothing() end) TimerStart(t, 1.0, true, () => DoNothing() end) 7. 类型继承。 typedef handle unit 8. 内置类型 int 等同于jass里的integer float 等同于jass里的real string 等同于jass里的string bool 等同于jass里的boolean void 等同于jass里的nothing 不可被继承 function 等同于jass里的code 不可被继承,类型需要指明参数和返回值的类型,例如 local foo:(int,int):int -- 语法错误 foo = (a:int):int => return a end foo = (a:int, b:int):int => return a + b end 9. 模块化 -- ModuleA文件 -- 局部变量模块外不可见 local a = 1 -- 使用export让模块外可见 export b = 2 -- ModuleB文件 local A = import 'ModuleA' local a = A.a -- 语法错误 local b = A.b 10. 对象 -- Calc文件 local a = 1 export b = 2 export function init(c:int):void b = a + c end -- Main文件 local Calc = class 'Calc' local a = Calc(10) 11. 函数重载 function add(a:int, b:int):int return a + b end function add(a:string, b:string):string return a + b end local x = add(1, 2) -- 3 local y = add("1", "2") -- "12"
1 下一页