BBSでジョーカーさんが質問されていた「スキル使用時、ゼニー消費しない」という効果を持ったアイテムなどの実装をしたいと思います。
具体的には bonus bNoZeny という新ボーナスを作ってみます。
改造対象は
db/const.txt
src/map/map.h
src/map/pc.c
src/map/skill.c
の4ファイルです。
今までと比べると難しくなりますが、頑張っていきましょう。
まず、const.txtに「bNoZeny」という新ボーナスの定義をします。
最新版ではbNoKnockback 2010が最後の要素なので、2011番にでもbNoZenyを定義させます。
const.txt 319行目あたり*
bFixDamage 2009
bNoKnockback 2010
bNoZeny 2011
さらに、map.hに「2011番はこのフラグを立てますよ」という定義もしてあげます。
最新版では850行目あたり、順番に左から2006、2007…~2010となっているので、2010番「SP_NO_KNOCKBACK」の後ろに2011番「SP_NO_ZENY」という新フラグを定義させます。
map.h 850行目あたり*
SP_NO_CASTCANCEL2,SP_INFINITE_ENDURE,SP_ITEM_NO_USE,SP_FIX_DAMAGE,SP_NO_KNOCKBACK, // 2006-2010
SP_NO_ZENY, // 2011
フラグの設定は出来ましたが、数字なのか文字なのか、このフラグはどんな種類のフラグなのか定義する必要があります。
同じくmap.hから、少し戻って260行目あたりに変数の定義をしている場所があります。
引数は必要ないと思うので、一番最後にでも追加しておきます。
これまたno_knockbackの後ろにno_zenyを付け加えます。
map.h 260行目あたり*
unsigned no_knockback : 1;
unsigned no_zeny : 1;
次にpc.cへ、「装備品による能力等のボーナス設定」という箇所を弄ります。
ここに新ボーナスを付け加えれば正式にbNoZeny専用のフラグが立ちます。
1989行目あたり、SP_NO_KNOCKBACKの後にSP_NO_ZENYのフラグ操作を加えます。
pc.c 1989行目あたり*
case SP_NO_KNOCKBACK:
sd->special_state.no_knockback = 1;
break;
case SP_NO_ZENY:
if(sd->state.lr_flag != 2)
sd->special_state.no_zeny = 1;
break;
具体的な意味は省きますが、これで「bNoZeny」というボーナスを認知した時、「special_state.no_zeny」というフラグが立つようになりました。
しかし、このままでは肝心の「スキル使用時Zenyを消費しない」という効果が発揮されません。
そこで、実際にZenyを消費しているskill.cの該当項目を探します。
例としてメマーナイトのゼニー消費を抑えます。
8170行あたりの特殊な消費処理の部分、zenyを操作している部分の
skill.c 8170行目あたり*
case MC_MAMMONITE://メマー
if(pc_checkskill(sd,BS_UNFAIRLYTRICK)>0)
zeny = zeny*90/100;
break;
を次のように
case MC_MAMMONITE://メマー
if(sd->special_state.no_zeny)
zeny = 0;
else if(pc_checkskill(sd,BS_UNFAIRLYTRICK)>0)
zeny = zeny*90/100;
break;
と、special_state.no_zenyのフラグが立っている場合はZeny消費を抑えるという効果にします。
次項のアンフェアリートリック効果のため、else ifを忘れないでください。
あとはアイテムに新ボーナス「bonus bNoZeny」を設定すれば完成です。
item_db.txtのequip_scriptの項でも何でも、
bonus bNoZeny,0;
を追加すれば、「スキル使用時、Zenyを消費しない」という効果を持ったアイテムの完成です。
最後に、弄る前に該当ファイルのバックアップと、弄った後のリメイクを忘れずに。お疲れ様でした。
Blaze 2007年01月09日(火)23時41分 編集・削除
書いた後に気付いたのですが、skill.cの弄る箇所、メマーナイトの箇所よりも最終的のZeny消費の箇所を弄った方が賢明のようです。
skill.cの8954行あたり、Zeny消費の項
if(zeny > 0) // Zeny消費
pc_payzeny(sd,zeny);
の部分を
if(zeny > 0 && !(sd->special_state.no_zeny)) // Zeny消費
pc_payzeny(sd,zeny);
に変更するだけで他のスキルもZenyを消費するのを抑える事が出来ます。