五、重写与立绘相关的过程
Ns中用ld显示立绘只有左中右三个,而如果有4个人物,或者人物有移动特效等等,ld就无能为力了。所以所有立绘都要基于lsp重写。包括下列函数:
chon - 立绘的载入,例如chon(1, "ta01aac1", 512, 0的意思是在(512, 0)位置载入文件名为"ta01aac1"的立绘,编号为1。
choff - 立绘的擦除 - choff(1)是擦除1号立绘,而choff(-1)是擦除所有立绘
efex - 立绘的移动 - 有两种,一种是现成立绘移动,另一种是载入立绘并移动,efex的第一个参数若为正,则指代待移动立绘的编号,。移动不立即执行,需要遇到efex(-1, 200)这样的语句才会执行。
ef - 立绘的震动效果
主要就是这几个。SFA立绘与Ns的lsp主要区别在于,①编号大的会重叠在在编号小的之上,这与Ns的次序是相反的;②立绘的横坐标是图片中心的横坐标,这样转换坐标时有点麻烦,需要先用lsp载入图片,再获取其尺寸,再将横坐标减去1/2*图片宽度得到左边缘的坐标。

(立绘的层次)
替换用Perl脚本片段如下:
$flag ++ if s/chon\(\s*(\d+),\s*("\w+"),\s*CENTER\s*\)/chon_c $1,$2/;
$flag ++ if s/chon\(\s*(\d+),\s*("\w+"),\s*NON\s*\)/chon $1,$2/;
$flag ++ if s/chon\(\s*(\d+),\s*("\w+"),\s*(\d+),\s*(\d+)\s*\)/chon_d $1,$2,$3,$4/;
$flag ++ if s/chon\(\s*(\d+),\s*("\w+"),\s*(\d+)\s*\)/chon_d $1,$2,$3,0/;
$flag ++ if s/chon\(\s*(\d+),\s*("\w+"),\s*CENTER,\s*(\d+)\s*\)/chon_d $1,$2,512,$3/;
$flag ++ if s/choff\(\s*(-?\d+)\)/choff $1/;
$flag ++ if s#efex\((\d+),\s*\d+,\s*(\d+),\s*(\d+)\)#efex $1,$2,$3\r\nefexon $1,200#;
$flag ++ if s#efex\((\d+),\s*12,\s*(\d+),\s*(\d+),\s*("\w+"),\s*(\d+),\s*(\d+)\s*\)#efex2 $1,$2,$3,$4,$5,$6\r\nefexon $1,200#;
$flag ++ if s#efex\(-1,\s*(\d+),\s*(\d+)\s*\)#;efexon $1,$2#; #由于实现上的困难,改成依次移动
$flag ++ if s#ef\(\s*(-?\d+),\s*\d+,\s*(\d+),\s*(\d+),\s*(\d+)\)#ef $1,$2,$3,$4#;
Ons脚本中相关自定义过程如下:
;-----从原立绘编号返回Ons立绘编号(chconst-原编号),由于SFA中是编号大的在上,和Ns是反的-----
*getchnum
getparam %chtmp
mov %chtmp,chconst-%chtmp
return
;-----checkalpha-判定此立绘的透明模式是copy还是alpha-----
*checkalpha
getparam $alphatmp
if $alphatmp="black" mov $alphatmp,":c;":goto *checkalpha_end
if $alphatmp="white" mov $alphatmp,":c;":goto *checkalpha_end
split $alphatmp,"_",$15,$16
if $15="ic" mov $alphatmp,":c;":goto *checkalpha_end
mov $alphatmp,":a;"
*checkalpha_end
return
;-----显示立绘-----
*chon ;对应于chon(3, "ta01aaa2", NON)
getparam %chontmp,$chonstmp
getchnum %chontmp
checkalpha $chonstmp
lsp %chtmp,$alphatmp+"grp/"+$chonstmp+".jpg",?0[%chontmp][0],?0[%chontmp][1]
return
*chon_d ;对应于chon(1, "ta01aac1", 512, 0),横坐标是立绘中心的坐标
getparam %chontmp,$chonstmp,%11,%12
getchnum %chontmp
checkalpha $chonstmp
lsp %chtmp,$alphatmp+"grp/"+$chonstmp+".jpg",0,0
getspsize %chtmp,%13,%14
mov ?0[%chontmp][0],%11-%13/2
mov ?0[%chontmp][1],%12
mov ?1[%chontmp][0],?0[%chontmp][0]
mov ?1[%chontmp][1],?0[%chontmp][1]
amsp %chtmp,?0[%chontmp][0],?0[%chontmp][1] ;原脚本中chon的参数是立绘中心的横坐标
return
*chon_c ;对应于chon(5, "white", CENTER),立绘在中间
getparam %chontmp,$chonstmp
getchnum %chontmp
checkalpha $chonstmp
lsp %chtmp,$alphatmp+"grp/"+$chonstmp+".jpg",0,0
getspsize %chtmp,%13,%14 ;开了两个数组,分别储存立绘现在的横纵坐标,和将要移动到位置的横纵坐标,在efex中要用到
mov ?0[%chontmp][0],(%width-%13)/2
mov ?0[%chontmp][1],(%height-%14)/2
mov ?1[%chontmp][0],?0[%chontmp][0]
mov ?1[%chontmp][1],?0[%chontmp][1]
amsp %chtmp,?0[%chontmp][0],?0[%chontmp][1]
*chon_c_end
return
;-----擦除立绘和CG-----
*choff
getparam %chofftmp
if %chofftmp=-1 goto *choff_m1;立ちCG消去
if %chofftmp=18 goto *choff_m1;没弄懂原脚本中参数18指什么,姑且认作全消
getchnum %chofftmp
csp %chtmp
mov ?0[%chofftmp][0],0
mov ?0[%chofftmp][1],0
goto *choff_end
*choff_m1
getchnum 1
for %1=1 to 20
csp %chtmp+1-%1
mov ?0[%1][0],0
mov ?0[%1][1],0
mov ?1[%1][0],0
mov ?1[%1][1],0
next
*choff_end
return
;-----元素震动时的特效-----
*ef
getparam %efexn,%efexa,%efexb,%efext
isskip %0
if %0=1 goto *ef_end
if %efexn!=-1 jumpf
if %efexa=0 quakey %efexb/2,%efext:goto *ef_end
if %efexb=0 quakex %efexa/2,%efext:goto *ef_end
quake (%efexa+%efexb)/4,%efext
goto *ef_end
~
getchnum %efexn
mov %efexi,%efext/20
for %efext=1 to %efexi
mov %11,%efext mod 4
if %11=1 mov %efexc,0-%efexa:mov %efexd,%efexb
if %11=2 mov %efexc,0-%efexa:mov %efexd,0-%efexb
if %11=3 mov %efexc,%efexa:mov %efexd,0-%efexb
if %11=4 mov %efexc,%efexa:mov %efexd,%efexb
;wait 10
amsp %chtmp,?0[%efexn][0]+%efexc,?0[%efexn][1]+%efexd
print 1
next
amsp %chtmp,?0[%efexn][0],?0[%efexn][1]
print 1
*ef_end
return
;-----立绘移动的特效-----
*efex
getparam %efexn,%efexa,%efexb
getchnum %efexn
getspsize %chtmp,%11,%12
mov ?1[%efexn][0],%efexa-%11/2
mov ?1[%efexn][1],%efexb
return
*efex2
getparam %efexn,%efexa,%efexb,$chonstmp,%efexc,%efexd
chon_d %efexn,$chonstmp,%efexc,%efexd
efex %efexn,%efexa,%efexb
return
*efexon
;执行立绘移动,50ms刷新一次——但是在渣机上测试发现卡的要死,故把wait注释掉了
getparam %efexn,%efext
isskip %30
if %30=1 goto *efexon_skip
mov %efexi,%efext/50
mov %efexa,(?1[%efexn][0]-?0[%efexn][0])/%efexi
mov %efexb,(?1[%efexn][1]-?0[%efexn][1])/%efexi
for %efexc=1 to %efexi-1
getchnum %efexn
amsp %chtmp,?0[%efexn][0]+%efexa*%efexc,?0[%efexn][1]+%efexb*%efexc
print 1
;wait 50
next
*efexon_skip
mov ?0[%efexn][0],?1[%efexn][0]
mov ?0[%efexn][1],?1[%efexn][1]
getchnum %efexn
amsp %chtmp,?1[%efexn][0],?1[%efexn][1]
print 1
return
立绘的移动和震动在PC上试验无任何问题,而自己的爪机上卡顿严重,故索性把其中的wait注释掉,不控制时间了。
六、其它特效
剩下的基本上就是写零散的特效了,能实现就实现,不能就ignore掉。在检查了最初的几个脚本后,发现接下来的文件中unknown的语句越来越少,然后只需更改Perl脚本中输入文件控制变量$bname的内容,可一次输出全部文本。