/* 配置するだけでそのルームをPT戦専用ルーム化する もちろんの事だがOnPCイベントを全て有効にしなければ正しく動作しない 挙動の定義 通常のPvPと同じように一人のPCを呼び込む→同時に@recallpartyを併用してPTを集める ルーム自体には動作をチェックするNPCが状況を保持 一応リーダーが死亡するとPT壊滅という処理をしてます 設定 一番下の方にBattleConfigがあります 今のところかなり未実装が多いですがコメントの通りに実装してある部分もあります simple仕様 仕様の都合で配置マップを「-」にすると全MAP判定してしまうのでDUP配置しにくい マップフラグは検査してないのでマップフラグをpvpにしておくこと 後はスクリプト名をユニークにしそれに合わせたPvPTransを配置すれば一応複数作れますが 複数作った場合の挙動は未定義。たぶんエラーでないと思うが想定外が起きても知りません あと鯖管用に近いのでdebugmesが各所に現れます <免責> 投稿者、名無し@は修正義務を負いません 改変、再配布も一切制限無く有効に活用していただければ幸いです しかし改変、再配布等によってMAP鯖に正常に読み込めない等の責任は一切負いません */ //このNPCはテスト用です prontera.gat,163,174,4 script PvPTrans 112,{ function GETDATA; function NAME; function ENTRYPT; if('MaxPT==0) GETDATA 1; while(1){ GETDATA 0; NAME; mes "PTvsPTルームに転送します"; mes "現在のマップは"+'Map$+"でPTvsPTが開催されています"; mes "出場PT状況:"+'NowPT+"PT出場しています"; switch( select("パーティーエントリー 注:一人登録でPT登録になります","ルーム情報の更新")){ case 1: ENTRYPT; break; case 2: break; } next; } function ENTRYPT { set '@PID,getcharid(1); if('@PID==0){ mes "あなたはPTに所属していません"; return; } GETDATA 0; if('NowPT >= 'MaxPT){ mes "登録PT上限です"; mes "現在は登録出来ません"; return; } warp 'Map$,0,0; gmcommand "@recallparty "+getpartyname('@PID); end; } function NAME { mes "[PTvsPT専用転送員]"; } function GETDATA {//コピペでPTvsPTルームを増やす場合ここを合わせる必要がある if(getarg(0)!=0){ set 'NowPT,getvariableofnpc('NowPT,"Checker"); set 'Map$,getvariableofnpc('Map$,"Checker"); set 'MaxPT,getvariableofnpc('MaxPT,"Checker"); } else { set 'NowPT,getvariableofnpc('NowPT,"Checker"); } return; }//ここまで } //PTVSPTルームにしたい場所に配置するのこと 間違っても[map.gat,x,y,d]を[-]にしない事 pvp_y_1-2.gat,0,0,0 script Checker -1,{ function DELPT; function ISLEADER; function MAPSHOUT; function FINDPT; function UNITDIE; OnPCLogin: OnPCMoveMap: set '@PID,getcharid(1); set '@AID,getcharid(3); debugmes "[Entry]:PID"+'@PID+" AID"+'@AID; FINDPT '@PID,'@AID; end; OnPCLogout: OnPCDie: set '@PID,getcharid(1); set '@AID,getcharid(3); UNITDIE '@PID,'@AID; end; // //以下はFunctionの実体化 function DELPT {//死亡したPCのPTを押し出すがこれが呼び出された時は明示的にPTIDが来てるものとする debugmes "[PTDelete]:getarg(0)"+getarg(0); set 'NowPT,'NowPT-1; sc_start 264,7,10; warp "SavePoint",0,0; gmcommand "@recallparty "+getpartyname(getarg(0)); set 'PTID[getarg(0)][0],0; return; } function MAPSHOUT {//ただのMapannouce関数だけど他にもやりたい事付ける時はここに mapannounce 'Map$,getarg(0),16; return; } function ISLEADER {//リーダーチェック そうじゃなかったら死亡したまま放置 set '@name$,getpartyleader('PTID[getarg(0)][0]); set '@my$,getcharname(getcharid(0)); debugmes "[Leader Name]:"+'@name$+"がパーティーリーダです"; if('@name$ == '@my$){ MAPSHOUT "[情報]:パーティー"+getpartyname('PTID[getarg(0)][0])+"のリーダーキル"; debugmes "[Leader is Dead]:PT単位で排除します"; DELPT getarg(0); return; } if('@name$ == ""){ debugmes "[Unknown]:リーダー取得失敗"; } debugmes "[NoLeader]:LEADERじゃないキャラが死亡しました"; return; } /* チェックが甘いので正規に登録したPTがAとBがあったとき・・・ Aから脱退→Bに加入してしまうと死亡時にはBのPTとして処理されます PvPルームではPT要請が出来ないようにしてしまったほうがいいかも */ function UNITDIE {//ユニットが死亡したら呼び出す for(set '@i,0; '@i < 'MaxPT; set '@i,'@i+1){ if(getarg(0) == 'PTID['@i][0]){//所属PT発見 debugmes "[DelUnit]:所属PT"+getarg(0)+" '@i"+'@i+ "getarg(1)"+getarg(1); if('BattleMode) ISLEADER '@i,getarg(1);//’BattleModeが設定されてたら放置 return; } } warp "SavePoint",0,0;//PTIDに検索して居なかった=PT脱退or不正侵入orPTの組み替えをしている return; } function FINDPT {//PT検索関数 for(set '@i,0; '@i < 'MaxPT; set '@i,'@i+1){ if(getarg(0)=='PTID['@i][0]){ debugmes "[FindPTID]:PTIDに登録されていましたので関数を抜けます"; return; } } for(set '@i,0; '@i < 'MaxPT; set '@i,'@i+1){//登録されていない新規PT if('PTID['@i][0]==0){//空PTIDを探す getpartymember getarg(0); set 'PTID['@i][0],getarg(0); set 'PTID['@i][1],$@partyemembercount;//今のところ無意味 set 'PTID['@i][2],getarg(1);//AIDも未実装 set 'NowPT,'NowPT+1;//参加しているPT数を更新 debugmes "[Entry]:登録ID"+'@i+"番目に登録しました"; return; } } //通常これ以下には来ない 或いは同時にエントリーして最大越えた時だけ debugmes "[MaxConnectOver]:PT最大数を超えた登録により排除"; warp "SavePoint",0,0; return; } //BattleConfig OnInit: set 'MaxPT,36;//MAPに同時に参加出来る限界数 set 'NowPT,0;//MAPに存在するPT数 set 'BattleMode,0;//1以上にするとリーダーが死んでも強制退場が発動しない set 'MaxMember,12;//PTの最大メンバ数だけど未実装 set '@dummy,getmapxy('Map$,'x,'y,1);//自動的にマップ位置を読み出す [-]チェックをしていないので注意 もし-だと鯖落ちします end; } /* おまけ的蛇足豆知識 Function毎に分けてしまえばNo more gotoが結構楽に出来ます(逆にこれがgotoの代わりに増えますが) 後はラベルをそのままFunctionに置き換えてしまえば同値の構造が得られます(もし同値にならない場合は構造がおかしいor間違っている) また保守が楽にはなるので試してみるのはいかかでしょうか? 同じ事やるときはFunction {}のコピペで済みますし mes "[NPCの名前]";とか入力がコピペで済むにせよ function NAME { mes "[NPCの名前]";}とかに展開しちゃったほうが スクリプト読むとき楽です */