|
【活动构思】 此活动主要是以玩家比武为基础,在规定的人数中通过比武选出第一名,给予其随机奖励。彰显了网络游戏中优胜劣汰、胜者为王的游戏思想。 增加1个新地图做为活动地图、增加2名NPC对活动进行控制及奖励。玩家在规定的位置进入活动地图中,当参加活动的人数达到规定人数后,任何一名玩家都可以申请比武开始。比武开始后即不允许其他人进入活动地图里,只有参加此次比武活动的玩家在里面PK,通过PK,最终只剩下一名玩家,这一名玩家就是此次比武的优胜者,他可以向NPC索取应得的奖励,NPC随机在多种奖品中选一种给他,并向全服务器所有玩家公告优胜者角色名,最后把他送出活动地图。下一次比武活动随即开始入场。
【脚本实现】 要想达到上述活动构思,必须有一个好的脚本来实现一切功能。常做脚本的朋友可能已经通过活动构思看出来了,其主要难点在于: 1、负责入场控制的NPC如何判断当前是否允许玩家入场; 2、负责入场控制的NPC如何判断前一场比武活动已经结束; 3、负责场内比武控制的NPC在场内只有一名玩家的时候,如何判断此玩家是通过PK优胜下来的,还是刚刚进来的第一名玩家; 以上三点,我是通过多NPC共用单脚本及使用局部变量来解决的。也就是说,入场控制NPC和场内比武控制NPC共用一个脚本,并在此脚本中设置一个局部变量,此变量代表着比武活动状态。两个NPC可以通过读取此变量来做出相应的动作,也可以根据活动当前进行的程度来改写此变量。可能我这样说,大家还是不太明白,那就请看脚本吧: 前提条件: 1、入场控制NPC--冰侠客;场内比武控制NPC--雪至尊。我瞎起的名,你也可以换两个好听的NPC名; 2、入场控制NPC在长城以南(地图序号为1);比武活动控制NPC在新增地图--冰雪屋(地图序号110,此序号要视你的map.sdb自行设置); 3、一次比武活动定员30人。这是范例中设置的,你也可以根据服务器具体情况定为其它数; 4、此脚本文件名为:冰雪论剑.txt 保存在Script目录中。
unit 冰雪论剑;
interface
function GetToken (aStr, aToken, aSep : String) : String; function CompareStr (aStr1, aStr2 : String) : Boolean; function callfunc (aText: string): string; procedure print (aText: string); function Random (aScope: integer): integer; function Length (aText: string): integer; procedure Inc (aInt: integer); procedure Dec (aInt: integer); function StrToInt (astr: string): integer; function IntToStr (aInt: integer): string; procedure exit;
procedure OnGetResult (aStr : String); procedure OnLeftClick (aStr : String);
implementation
procedure OnLeftClick (aStr : String); var Str : String; Race : Integer; begin Str := callfunc ('getsenderserverid'); if Str = '1' then begin //如果所在地图为长城以南,则 Str := callfunc ('getsenderrace'); Race := StrToInt (Str); if Race = 1 then begin Str := 'showwindow ./help/冰雪屋入口NPC.txt 1'; print (Str); exit; end; end; if Str = '110' then begin //如果所在地图为活动地图,则 Str := callfunc ('getsenderrace'); Race := StrToInt (Str); if Race = 1 then begin Str := 'showwindow ./help/冰雪屋内NPC.txt 1'; print (Str); exit; end; end; end;
procedure OnGetResult (aStr : String); var Str, Name : String; iCount : Integer; zhuangtai : Integer; iKind : Integer; begin if aStr = 'close' then begin exit; end; if aStr = 'jinru' then begin //如果玩家选择进入活动地图,则 Str := callfunc ('getusercount 110'); //取出活动地图当前人数 iCount := StrToInt (Str); if iCount > 30 then begin //如果活动地图当前人数超过定员 print ('say 冰雪屋里超员了!请下次再来...'); exit; end; if zhuangtai <> 1 then begin //如果活动尚未开始,则传送此玩家到活动地图 Name := callfunc ('getsendername'); Str := 'movespace ' + Name; Str := Str + ' user 110 43 53'; print (Str); exit; end;
print ('say 正在论剑比武!请下次再来...'); //如果活动已经开始,则不允许进入,并提示玩家下次再来 exit; end; if aStr = 'kaishi' then begin //如果玩家申请开始比武,则 if zhuangtai = 1 then begin //如果当前状态为正在进行活动,则不允许玩家再次申请开始 print('say 论剑比武已经开始了!还申请什么?'); exit; end; Str := callfunc ('getusercount 110'); iCount := StrToInt (Str); if iCount > 29 then begin //如果活动地图中大于等于定员人数,则 zhuangtai := 1; //改写状态为正在进行活动 print ('sendsendertopmsg 冰雪论剑现在开始!!'); //向全服务器玩家公告此次活动开始 print ('say 开始了!各位大侠请出手吧!'); exit; end;
print ('say 屋内不足30人!不能开始论剑比武!'); //如果场内没有达到定员,则提示申请人 exit; end; if aStr = 'lingjiang' then begin //如果玩家选择领取奖品 if zhuangtai = 1 then begin //如果当前状态为正在进行活动 Str := callfunc ('getusercount 110'); iCount := StrToInt (Str); if iCount = 1 then begin //如果活动场地内仅剩一名玩家,则证明此玩家为优胜者 Str := callfunc ('checkenoughspace'); //读取优胜者物品栏 if Str = 'false' then begin print ('say 物品栏已满~'); exit; end;
iKind:= Random (7); //产生0~6的7个随机数,配合下面一段实现随机发奖品给玩家 if iKind = 0 then begin Str := 'putsendermagicitem 太极拳套 @雪至尊 4'; print (Str); end; if iKind = 1 then begin Str := 'putsendermagicitem 太极日剑 @雪至尊 4'; print (Str); end; if iKind = 2 then begin Str := 'putsendermagicitem 太极月刀 @雪至尊 4'; print (Str); end; if iKind = 3 then begin Str := 'putsendermagicitem 太极神枪 @雪至尊 4'; print (Str); end; if iKind = 4 then begin Str := 'putsendermagicitem 太极斧 @雪至尊 4'; print (Str); end; if iKind = 5 then begin Str := 'putsendermagicitem 男子太极道袍 @雪至尊 4'; print (Str); end; if iKind = 6 then begin Str := 'putsendermagicitem 女子太极道袍 @雪至尊 4'; print (Str); end;
Name := callfunc ('getsendername'); //将优胜者送回长城以南 Str := 'movespace ' + Name; Str := Str + ' user 1 521 479 400'; print (Str);
Name := callfunc ('getsendername'); //向全服务器公告此次活动优胜者角色名 Str := 'sendsendertopmsg ' + Name; Str := Str + '赢得此次冰雪论剑比武胜利!!'; print (Str);
zhuangtai := 0; //设置当前状态为活动结束 exit; end;
print ('say 不剩最后一个人绝不发奖!'); //如果活动场地内还有其他人,则不允许领取奖品 exit; end;
print ('say 论剑比武还没开始呢!你着急了?'); //如果活动还没有开始,则不允许任何人领取奖品 exit; end; end;
end.
【其它设置】 为了配合活动,除了上述脚本要放在Script目录中以外,还需要进行以下配置: 1、增加活动地图 在Init/Map.sdb里增加一条数据(红字部分为字段名,是为了方便数据对照的,不需要加到文件中,下同): MapID,SmpName,MapName,TilName,ObjName,RofName,SoundBase,SoundEffect,MapTitle,boUseBowMagic,boUseChemistDrug,boUseDrug,boGetExp,boBigSay,boUsePowerItem,boUseGuildMagic,boUseMagic,boUseRiseMagic,boUseWindMagic,boUseBestMagic,boUseBestSpecialMagic,boUsePowerLevel,boUseEtcMagic,boCanChangeMagic,boMakeGuild,boItemDrop,boPosDie,boHit,boWeather,boPrison,boChangeLife,ChangePercentage,ChangeDelay,ChangeSize,Attribute,RegenInterval,EffectInterval,TargetServerID,TargetX,TargetY,boDark,boRain,boPick,Script,LoginServerID,LoginX,LoginY,boSetGroupKey,GroupKey,boPK,boEvent,EventAge,EventID,EventX,EventY,boNotAllowPK,boShop,SubMap,MotherMap,boNotUseHideItem,boShowMiniMap,boFirstPickUp,UseDay,StartHour,EndHour,SoundStart,SoundEnd,UseDrugName,boNotDeal, 110,main.smp,main.map,paradise.til,paradise.obj,paradise.obj,1054,9139,冰雪屋,TRUE,TRUE,TRUE,TRUE,,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,,TRUE,TRUE,TRUE,TRUE,,,,,,,,,1,520,478,,,,,1,500,500,,,,,,,,,,FALSE,,,,,,,,,,,,FALSE, 2、增加活动控制NPC 在Init/Npc.sdb里增加两条数据: Name,ViewName,Virtue,VirtueLevel,NpcText,boMinimapShow,boSale,boSeller,boProtecter,boObserver,boAutoAttack,boHit,animate,shape,Image,Damage,Armor,ArmorHead,ArmorArm,ArmorLeg,Life,AttackSpeed,Avoid,Recovery,SpendLife,HitArmor,ActionWidth,SoundStart,SoundAttack,SoundDie,SoundNormal,SoundStructed,EffectStart,EffectStructed,EffectEnd,HaveItem,AttackMagic,AttackSkill,HaveMagic,RegenInterval,boBattle,boRightRemove, 冰侠客,冰侠客,0,,,TRUE,,,,,,,62,81,235,0,0,,,,20000,0,0,0,0,,0,,,,,,,,,,,,,,,, 雪至尊,雪至尊,0,,,TRUE,,,,,,,62,81,235,0,0,,,,20000,0,0,0,0,,0,,,,,,,,,,,,,,,, 3、向系统注册脚本 在Script/Script.sdb中增加一条数据(注意,最前面的字段值135是根据我服务器的情况设置的脚本编号,你可以根据自己的情况设置为其它数值): Name,FileName,Desc, 135,冰雪论剑.txt,, 4、增加活动死亡复活点 在Init/PosByDie.sdb中增加一条数据(最前面的字段值50是根据我服务器的情况设置的复活点编号,你可以根据自己的情况设置为其它数值): Name,Server,DestServer,DestX,DestY,Notice, 50,110,1,521,479,, 5、增加活动NPC刷新点 在Setting/CreateNpc1.sdb中增加一条数据(注意,最前面的字段值104是根据我服务器的情况设置的,你可以根据自己的情况设置为其它数值;最后的135是第3条中设置的脚本编号): Name,NpcName,X,Y,Count,Width,Notice,BookName, 104,冰侠客,524,474,1,1,135,, 在CreateNpc110.sdb中增加一条数据(如果无此文件请新建它): Name,NpcName,Notice,X,Y,Count,Width,BookName, 1,雪至尊,135,37,47,1,2,, 5、增加HELP文件 在HELP目录中新增两个文件:
冰雪屋入口NPC.txt <trade> <title>冰侠客</title> <image name=z81 value=235> <text> 欢迎参加本次冰雪论剑比武大会!以武会友!以武论英雄!! </text> <command send='close'>关闭</command> <command send="jinru">进入冰雪屋</command> </trade>
冰雪屋内NPC.txt <trade> <title>雪至尊</title> <image name=z81 value=235> <text> 屋内够30人你就可以申请开始论剑比武!开战后击败屋内所有侠士才能赢得最后的胜利!! </text> <command send='close'>关闭</command> <command send="kaishi">申请开战</command> <command send="lingjiang">领取奖品</command> </trade>
【技术特点】 活动构思并没有什么新意,只是在脚本编写上做了一些新尝试。引入了多NPC共用单脚本的理念;引入了以局部变量表示某种状态进而控制活动全局的新概念;使用了新的公告函数,解决以往公告词中不得不带有系统添加的无用信息这一难题。
【测试要点】 我只是提供一个范例给大家,如果要在自己的服务器中测试这个活动要注意以下几点: 1、所有涉及到的地图编号、NCP编号、脚本编号的地方请根据自己服务器的实际情况自行设定,不要直接套用范例中的编号,因为实际情况不太可能完全相同。比如:范例中的活动地图编号是110,可能你的服务器中110这个编号已经分配给别的地图了。 2、所有涉及到地图名、NPC名、脚本文件名、HELP文件名的地方请根据自己服务器的实际情况自行设定,如果没有冲突,也可以使用范例中的名字,但要保证相互匹配。比如:脚本中打开NPC对话框时是指定的“./help/冰雪屋内NPC.txt”,那么在HELP目录下必须有“冰雪屋内NPC.txt”这个文件与之配套。 3、所有涉及到增加sdb文件新数据的情况,我已经提供了字段与数据的对应,请先对照看好再添加,因为版本不同,数据位置也不同,千万不要生搬硬套。 4、实际应用的脚本不要带注释,就是范例中所有蓝色带“//”的文字。要把注释及注释前面的空格全去掉。
【FAQ】 问:加了脚本以后,为什么启动TGS会在TGS目录里出现“Error-冰雪论剑-ongetresult.log”这样的错误日志文件? 答:这是因为脚本文件“冰雪论剑.txt”中有一处变量声明出错,请重新复制本贴中的脚本。
问:为何点NPC没有反应? 答:请先去掉“冰雪论剑.txt”中的所有注释及注释前的空格再运行。如果还没有反应,请检查脚本中指定的NPCHELP文件名与HELP目录中的文件名是否相同。如果只是冰雪屋内的NPC没有反应,请检查脚本中冰雪屋地图编号是否与map.sdb中冰雪屋地图编号一致。
问:为什么点活动NPC却出来其它NPC的对话框? 答:这是因为Script.sdb中冰雪论剑脚本编号与CreateNpc1.sdb(或CreateNpc110.sdb)中NPC使用的脚本编号不相同造成的。如何解决就不用说了吧。
问:比武过程中,死了的玩家还能就地复活,这是为什么? 答:这是因为PosByDie.sdb中新加的复活点地图编号与map.sdb中冰雪屋地图的编号不符造成的。请修改PosByDie.sdb中Server字段下的数据为冰雪屋地图编号。
问:死了是出去了,可是还能再进来,为什么? 答:请检查脚本文件中所有地图编号,把所有冰雪屋地图编号都修改正确。这样还能避免很多其它错误。
希望通过此脚本及设置的方法能给大家带来新的思想,新的理念,新的做法,出现更多更好的活动!!期待中。。。。
|