序:不知道有多少人看过《三国之见龙卸甲》,此刻我的心情与赵子龙如出一辙;人生就是一个圈,走了很久,回到原地。在这个圈中,你会遇到很多朋友,他们很多人早已离去,很多人即将离去,剩下的人,会见证你的离去。过去的日子,在支离破碎的记忆中重拼,或多或少能重温下昔日感觉,那随逝去时光而疏远的感觉。
我知道他们走完了自己的圈,然后离开;我也即将完成自己的圈,画上个完美的句点。
几小时前,我用C2I写的系统遇到BUG,我找老狼帮我看下;他给了我他QQ空间的连接,我还以为他早研究透了C2I;在为自己少了个伟大的原创而感到泄气之余,朋友帮我给出了老狼连接中的内容:他不想碰WE,打算离开……
……
既然当初是在U9遇到的老狼——他也是我来U9认识的第一个朋友,于是我把这个东西首发U9,聊表怀念。赵子龙最后在战场上找回了昔日的感觉,我也去寻找下,当初一条YD的小蝌蚪,很傻很天真的感觉……
C2I生不逢时,直到魔兽快没落才引起重视,那么,在落日的余晖下,我一边介绍这个函数,一边缅怀老狼和昔日的时光。
==================================================YD的小蝌蚪分割线===========================================
H2I大家不会陌生,即便你不会Jass,想必也见过。
[jass]function H2I takes handle h returns integer
return h
return 0
endfunction[/jass]
如果你不会这东西,那甚至都不能说自己会JASS,因为它正是JASS的精华所在。而我现在要介绍的,是C2I
[jass]function C2I takes code c returns integer
return c
return 0
endfunction
function I2C takes integer i returns code
return i
return null
endfunction
[/jass]
最初用c2I做演示,萌发自Hackwaly一篇文章
http://www.islga.org/bbs/read.php?tid=2268&keyword= ;我先问问大家,闪避光环和星际里仲裁者的隐形光环,是不是两个效果安全不同的光环——其实,这两个光环如果你做出来,你会发现,它们的差别,仅仅是核心两行代码不同:
闪避光环:添加魔法书(含闪避)
禁用魔法书
隐形光环:添加幽灵技能
关闭单位碰撞
但是,仅仅因为这两行代码不同,我们就要重复写很多行代码——那么,能不能把这两行代码当作参数,由函数调用,做成一个光环系统呢。
这便是我做这个系统最初的想法。
Hcakwaly的文章里没有提到C2I,最初我是用H2I来转换code以保存到缓存,结果提示出错;于是我妙想天开地依葫芦画瓢写了C2I,结果成了。回想起来,H2I也是欺骗系统的手段,感觉电脑就是电脑,太好骗了。
起初用这个C2I相当顺利,我一口气做了好几个技能;后来在做月经光环时,遇到难题——因为这个光环的效果是将靠近的敌人变成女人,也就是个周期性释放的群体妖术光环,大家来看下这段代码:
[jass]function Aura_yuejing_On takes nothing returns nothing
local unit u =CreateUnit(Player(0),'ushd',GetUnitX(GetEnumUnit()),GetUnitY(GetEnumUnit()),0)
call UnitAddAbility(u,'ANhx')
call StoreInteger(udg_GC,I2S(H2I(GetEnumUnit())),"AuraSystemUnit",H2I(u))
call IssueTargetOrder(u, "hex", GetEnumUnit())
set u=null
set hero=null
endfunction
……
call ForGroup(targetgroup,function Aura_yuejing_On )[/jass]
因为是演示,所以我这写的是为Player(0)创建辅助单位,但实际应该是为拥有光环单位的所有者创建,要不你这个演示就只有给玩家一用了。可是,function Aura_yuejing_On是个单位组调用的函数,除非这个单位组是在触发器动作的函数里,那样我们可以通过GetTriggerUnit()等来传递数据。记得不久前有人问我,不用全局变量如何给单位组传递数据呢,我告诉他无解,因为即便你用缓存,那也相当于一个全局变量,因为没法进行数据绑定。
MS国内国外的WEer都遇到过这样的难题,举个例子,我们local unit u=CreateUnit(xxx)创建了个单位并用局部变量保存,然后我们要选取一个单位组里所有单位来攻击这个单位,这个时候,你只有两个选择
一、
[jass]function Attack takes nothing returns nothing
call IssueTargetOrder(GetEnumUnit(),"attack",bj_lastCreatedUnit)
endfunction
……
local unit u=CreateUnit(xxx)
set bj_lastCreatedUnit=u
call ForGroup(targetgroup,function Attack)[/jass]
这种方法是利用全局变量才把值传递到单位组函数里,但是想必很多会JASS的人都尽量避免使用全局变量,理由我就不说了。
二、
[jass] local unit u=CreateUnit(xxx)
local unit u1
……
loop
set u1=FirstOfGroup(targetgroup)
exitwhen u1==null
call IssueTargetOrder(u1,"attack",u)
call GroupRemoveUnit(targetgroup,u1)
endloop [/jass]
这种方法可以说是反其道而行之,既然我们无法往单位组函数里输送数据,那何不把单位组拆开,把里面的单位揪出来让他们去干活。
目前这种写法,是最常见的,国内外很多优秀的演示都使用该方法。
那么,有第三种方法么,你说“有”,然后给出
[jass]function Attack takes nothing returns nothing
call IssueTargetOrder(GetEnumUnit(),"attack",I2U(GetStoreInteger(udg_GC,"Attack","TargetUnit")))
endfunction
……
local unit u=CreateUnit(xxx)
call StoreInteger(udg_GC,"Attack","TargetUnit",H2I(u))
call ForGroup(targetgroup,function Attack)[/jass]
我只能说这样很傻,因为这里没有可以绑定数据的对象,缓存跟全局变量没有区别,还不如就用第一种呢。或许你不服气,那我问你,如果这里同时有两个周期性群体技能,一个技能是风暴之锤,一个是妖术,我们要把辅助单位身上的技能等级设置得跟英雄身上的光环技能等级一样,那么你怎么做呢——如果这两个技能的等级不一样,你能用一个全局变量传递两个数据么。
再回顾下我们为何要用数据绑定,因为数据绑定之后,缓存就像一个全局变量数据,能把不同的数据区分开——这是我们需要的。可是,问题在于,这里没法使用数据绑定,因为没有绑定的对象。
在非触发器动作函数里的单位组而言,GetTriggerUnit等常用的绑定对像没有意义,唯一能获得的只有GetEnumUnit(),但我们又没法在选取单位组之前把数据绑定到GetEnumUnit()上。
为何我提倡WEer要YD,因为YD才能不拘一格;我想既然C2I可以像H2I一样应用,那能不呢个把code作为绑定的对象——这想法最初把我吓了跳,但很快激起我浓厚的兴趣。
于是,上面的代码,我这样写
[jass]function Attack takes nothing returns nothing
local unit u=I2U(GetStoredInteger(udg_GC,I2S(C2I(function Attack)),"Unit"))
call IssueTargetOrder(GetEnumUnit(),"attack",u)
set u=null
endfunction
……
local unit u=CreateUnit(xxx)
call StoreInteger(udg_GC,I2S(C2I(function Attack )),"Unit",H2I(u))
call ForGroup(targetgroup,function Attack)
[/jass]
结果,正如你猜测的那样,成功了……
[jass] local unit u=I2U(GetStoredInteger(udg_GC,I2S(C2I(function Attack)),"Unit")) [/jass]
多么荒诞不经的写法=。=!
就这样,我找到了个在单位组中传递数据的方法,前面的月经光环里单位组函数现在可以这样写
[jass]function Aura_yuejing_On takes nothing returns nothing
local unit hero=I2U(GetStoredInteger(udg_GC,I2S(C2I(function Aura_yuejing_On)),"Hero"))
local unit u =CreateUnit(GetOwningPlayer(hero),'ushd',GetUnitX(GetEnumUnit()),GetUnitY(GetEnumUnit()),0)
call UnitAddAbility(u,'ANhx')
call StoreInteger(udg_GC,I2S(H2I(GetEnumUnit())),"AuraSystemUnit",H2I(u))
call IssueTargetOrder(u, "hex", GetEnumUnit())
set u=null
set hero=null
endfunction [/jass]
如此一来,可以完美地解决传递数值问题。
看到这里,聪明的朋友可能要喷我了——function Aura_yuejing_On是固定的,"HERO"也是固定的,都固定死了,跟全局变量有何区别,这算哪门子数据绑定。
嘿嘿,奥秘就在下面
[jass]function XXX takes unit hero,code cFunOn returns nothing
call StoreInteger(udg_GC,I2S(C2I(cFunOn)),"Hero",H2I(hero)) [/jass]
……
请问大家,我在写数据时,可有把数据写死了,这里的cFunOn是不是固定的——当然,不是,这里cFunOn是传递过来的code,可以是月经光环,也可以是遗精光环,强奸光环,菊暴光环等等。
现在大家是不是对这个光环系统有点了解了:)
正如前面所说,光环之间的差异,就核心的几行代码而已——像月经光环和遗精光环,仅仅是输出不同而已;强奸光环跟菊暴光环,仅仅是接口不同而已。
而我们正是把这核心的几行代码,以code的形式,作为参数输入到光环系统,然后得到一个崭新的技能。
如果你觉得这个故事已经结束,那么才刚刚开始。
当我用这YD基于C2I构建的系统制作一个又一个光环时,我在感慨,闪避光环、致命一击光环、隐形光环、月经光环……那一个在以前看来不是高深莫测,现在Ctri C+Ctrl V再修改一两行代码,几分钟功夫就能搞定一个技能。
如果说过去是手工作坊,那现在是机械化大生产。回想起来,过去的岁月充满激情,也很有热血,现在感觉自己成了一个技术动物,跟机器似的。
感慨归感慨,但我还是很兴奋的;因为只要这个C2I一推广,我能像老狼一样引导一个潮流,去改变人们写JASS的习惯;而且我还可以把这个发到wc3c,说不定能混个精华什么的,只是不知道那么老外看到“月经光环”是什么反映,哇哈哈哈……
正当我做着蛋生鸡,鸡生蛋的美梦,这个美梦随同鸡蛋一起破灭了。
我发现了一个BUG。
本来光环系统已经没什么问题,可以发了;但出于贴心,我想把光环做得更人性化一些,增加了光环的删除,还有当单位死亡后删除光环而复活时又添加上,还有在指定的时间内单位拥有光环,但时间一过就取消……
最初挺顺利,但随后我发现,当删除光环后,再添加光环,没有任何效果。
我通过反复的调试,证实了这点;而且让我郁闷的是,我搞不清这是C2I固有的BUG,还是我的代码有BUG。
目前为止所知的C2IBug只是I2C的时候必须用个code变量来保存,否则出错。
我解决不了这个BUG,又不想求助于人——因为这是我的发现,我有权力去享受发现者的荣耀。
我也可以去掉删除光环又添加的画蛇添足的函数,直接把模板发布,这样能享受荣耀,但对不起良心。
由于还是其他事要做,我打算让那所谓的荣耀去见鬼——魔兽都没几天命了,你要劳什子荣耀做什么。
在我发布这个函数模板前,我看到老狼在线,于是跟他说晚上我要发布个演示,但有BUG,你帮我看下吧。
于是出现本文开头的那一幕。
最后多的我也不想说什么了,JASS这东西,本身BUG就很多,像那个让老狼很受伤的RPBUG,还有很多我们未知的BUG。虽然老狼答应帮我看演示,但我还是很难过,是的,人又少了一个。
曾经的WE界是个湖泊。作为小蝌蚪的我很黄很YD;现在的WE圈,只是个池塘 ,鳄鱼河马都上岸了,留下我这只井底之蛙。
这仅存的池塘也将干枯。
到目前为止,WE界离开了多少人,拿曾经出现过U9的人来说
lars zyl910 Illusion 八月天 天机鸟 earst ... 现在老狼也即将加入到他们的行列
以后技术上遇到难题,去找谁好呢,谁还能跟我讨论下WE(目前高手也还多,但不排斥YD的我的,还真没几个。希望Hackwaly不要走吧,我的朋友快走光了)。
呜呼,仅以这个带BUG的光环系统送别老狼,很怀念当初和老狼还有八月天一起YD的日子
《见龙卸甲》,YD是不是也要脱下斯巴达内裤去裸奔呢。
我的WE之路,尽头在哪里。
放上演示,注:当山丘第二次使用勃起光环,会出BUG。我将删除光环时的计时器由删除改成暂停,当单位死亡时候暂停,复活后恢复并重新运行函数,解决了之前的问题;但是这方法面临“在某个时间内当单位拥有光环技能”没用,希望大家能讨论下C2I和这个BUG,目前我通过BJDebugMsg定位,已经确定问题出在第二次使用技能时,计时器没有工作。