ブレナンのグレイルクエストでは、敵と会っても、「友好反応」「ワイロ」のどちらかが成功すれば、闘いを回避することができる。プログラムを書くのに難しい点は、どちらも闘いの前に1回しか試せないこと。そのため、enemy_party.Friendly_Reaction_triedとenemy_party.Bribery_triedという試行済フラグを作る。敵1人1人には、enemy[i].Friendly_Reactionで友好反応成功フラグ、enemy[i].Briberyでワイロ成功フラグを作る。また、友好反応が成功した敵にはワイロを試す必要はなく、ワイロが成功した敵に友好反応を試す必要はないことも考慮する必要がある。その上、敵全てが友好反応またはワイロにひっかかったら、戦闘を開始する前に戦闘を終了させることも考えなければならない。もちろん、戦闘終了後、これらのフラグは全リセット。
まず、友好反応とワイロのボタン表示のhtmlはこれ。
<input type="button" value="友好反応" onClick="click_Friendly_Reaction()"> <input type="button" value="ワイロ" onClick="click_Bribery()">
// 友好反応が必要な敵を見つける
function find_Friendly_Reaction_target() {
var i;
var found_target = enemy.length;
for (i = enemy.length - 1; i >= 0; i--) {
if (enemy[i].max_LIFE_POINT > 0 && enemy[i].Friendly_Reaction_tried === false && enemy[i].Bribery === false) {
found_target = i;
}
}
return found_target;
}
// ワイロが必要な敵を見つける
function find_Bribery_target() {
var i;
var found_target = enemy.length;
for (i = enemy.length - 1; i >= 0; i--) {
if (enemy[i].max_LIFE_POINT > 0 && enemy[i].Friendly_Reaction === false && enemy[i].Bribery_tried === false) {
found_target = i;
}
}
return found_target;
}
// 戦闘対象にはいる敵を見つける
function find_Aviod_Fight_target() {
var i;
var found_target = enemy.length;
for (i = enemy.length - 1; i >= 0; i--) {
if (enemy[i].max_LIFE_POINT > 0 && enemy[i].Friendly_Reaction === false && enemy[i].Bribery === false) {
found_target = i;
}
}
return found_target;
}
// 「友好反応」クリック
function click_Friendly_Reaction () {
if (enemy[0].max_LIFE_POINT === 0) {
add_msg("敵がいない。");
} else if (Pip.Mask_of_Friendship_currentSection === true) {
add_msg("友好の仮面ですべての敵から友好反応を得られた。");
combat.reset(); // 戦闘が始まる前に終了
} else if (Pip.Smarm_Oil === true) {
add_msg("友好オイルですべての敵から友好反応を得られた。");
Pip.Smarm_Oil = false;
data_magic[19].label = "塗る";
combat.reset(); // 戦闘が始まる前に終了
} else if (enemy_party.Friendly_Reaction_tried === true) {
add_msg("既に友好反応は試して終わっている。")
} else if (find_Friendly_Reaction_target() === enemy.length) {
enemy_party.Friendly_Reaction_tried = true;
add_msg("すべての敵と友好反応を試みた。");
if(find_Aviod_Fight_target() === enemy.length) {
add_msg("すべての敵と戦闘を回避できた。");
combat.reset(); // 戦闘が始まる前に終了
}
} else {
Friendly_Reaction_enemy();
}
}
// 友好反応の敵のサイコロを振る
function Friendly_Reaction_enemy() {
var target = find_Friendly_Reaction_target();
add_msg("友好反応を試みる。" + enemy[target].name + "のサイコロを1個振れ。");
dice.start(1, 'Friendly_Reaction_Pip()');
}
// 友好反応のピップのサイコロを振る
function Friendly_Reaction_Pip() {
var target = find_Friendly_Reaction_target();
add_msg(enemy[target].name + "のサイコロの目は" + dice.die1pip);
enemy[target].Friendly_Reaction_die1pip = dice.die1pip;
add_msg("ピップのサイコロを3個振れ。");
dice.start(3, 'Friendly_Reaction_decision()');
}
// 友好反応の正否を判定
function Friendly_Reaction_decision() {
var target = find_Friendly_Reaction_target();
add_msg("ピップのサイコロの目は" + dice.die1pip + " + " + dice.die2pip + " + " + dice.die3pip + " = " + dice.dice123pip);
if (dice.dice123pip < enemy[target].Friendly_Reaction_die1pip) {
add_msg(enemy[target].name + "との友好反応は成功した。");
enemy[target].Friendly_Reaction_tried = true;
enemy[target].Friendly_Reaction = true;
} else {
add_msg(enemy[target].name + "との友好反応は失敗した。");
enemy[target].Friendly_Reaction_tried = true;
enemy[target].Friendly_Reaction = false;
}
click_Friendly_Reaction();
}
// 「ワイロ」クリック
function click_Bribery () {
if (enemy[0].max_LIFE_POINT === 0) {
add_msg("敵がいない。");
} else if (enemy_party.Bribery_tried === true) {
add_msg("既にワイロは試して終わっている。")
} else if (find_Bribery_target() === enemy.length) {
enemy_party.Bribery_tried = true;
add_msg("すべての敵とワイロを試みた。");
if(find_Aviod_Fight_target() === enemy.length) {
add_msg("すべての敵と戦闘を回避できた。");
combat.reset(); // 戦闘が始まる前に終了
}
} else {
Bribery_enemy();
}
}
// ワイロの敵のサイコロを振る
function Bribery_enemy() {
var target = find_Bribery_target();
var found_gold = -1;
for (i = 0; i < Pip_event.length; i++) {
if (data_event[ Pip_event[i].id_num ].name === "金貨") {
found_gold = i;
}
}
if (enemy[target].Bribery_amount === 0){
add_msg(enemy[target].name + "はワイロを受けつけない。");
} else if (found_gold === -1) {
add_msg("ピップは金貨を持っていない。");
} else if (Pip_event[found_gold].num < enemy[target].Bribery_amount) {
add_msg("ワイロに必要な金貨が足りない。");
} else {
lose_event("金貨", enemy[target].Bribery_amount);
add_msg("ワイロを試みる。" + enemy[target].name + "のサイコロを2個振れ。");
dice.start(2, 'Bribery_decision()');
}
}
// ワイロの正否を判定
function Bribery_decision() {
var target = find_Bribery_target();
if (dice.dice12pip >= 8) {
add_msg(enemy[target].name + "のワイロは成功した。");
enemy[target].Bribery_tried = true;
enemy[target].Bribery = true;
} else {
add_msg(enemy[target].name + "のワイロは失敗した。");
enemy[target].Bribery_tried = true;
enemy[target].Bribery = false;
}
click_Bribery();
}