/* リネージュにおける防具や武器の強化について, jnethackから学んでみよう */
/* 実際にjnethackのコードを覗いて考えましょう */

/* !防具 */
/* !read.c の777行目〜942行目まで. JP版に関係ない部分がコメントになっていたが,
    不要なので削除した */
case SCR_ENCHANT_ARMOR:
{
  register schar s;
  boolean special_armor;
  boolean same_color;

  // !some_armorは, 装備されている防具から一つを適当に選ぶ関数
  // !従ってotmpは装備品へのポインタと考えてよい
  otmp = some_armor(&youmonst);
  // !防具の装備がない場合は, 特定のメッセージが出るが関係ないので削除
  // !混乱している時の処理が入るが関係ないので削除 
  /* elven armor vibrates warningly when enchanted beyond a limit */
  /* !エルフの防具は, 限界を超えて強化されると警告を発して震える */
  // !special_armorは選択された防具がエルフ防具か, 
  // !自分が魔法使いかつとんがり帽子の場合にセットされる 
  special_armor = is_elven_armor(otmp) ||
    (Role_if(PM_WIZARD) && otmp->otyp == CORNUTHAUM);
  // !same_colorは,
  // !巻物が呪われている場合は, 黒色ドラゴンの鱗鎧か黒色ドラゴンの鱗
  // !巻物が呪われていない場合は, 銀色ドラゴンの鱗鎧か銀色ドラゴンの鱗か
  // !リフレクションシールドの場合にセットされる
  // !ただし, 盲目の場合はセットされない
  if (sobj->cursed)
    same_color =
      (otmp->otyp == BLACK_DRAGON_SCALE_MAIL ||
       otmp->otyp == BLACK_DRAGON_SCALES);
  else
    same_color =
      (otmp->otyp == SILVER_DRAGON_SCALE_MAIL ||
       otmp->otyp == SILVER_DRAGON_SCALES ||
       otmp->otyp == SHIELD_OF_REFLECTION);
  if (Blind) same_color = FALSE;

  /* KMH -- catch underflow */
  // !sは巻物が呪われている場合は, -防具の強化値
  // !巻物が呪われていない場合は, 防具の強化値を示す
  s = sobj->cursed ? -otmp->spe : otmp->spe;
  // !rn2(x)は,0〜x-1の値をランダムに返す関数
  // !従って, 次の条件文の意味は
  // !s(防具強化値が), special_armorが真(エルフ防具等)の時は5より大きく,
  // !それ以外(通常の防具)の時は3より大きい, 
  // !かつ, 0〜s(防具強化値)-1の範囲の乱数値が0以外の場合真になる
  if (s > (special_armor ? 5 : 3) && rn2(s)) {
    // !真になった場合は蒸発する(OE失敗) 
    Your("%sはしばらくの間激しく%s%s,蒸発した.",
	 xname(otmp),
	 Blind ? nul : jconj_adj(hcolor(sobj->cursed ? NH_BLACK : NH_SILVER)),
	 Blind ? "振動し" : "輝き");
    if(is_cloak(otmp)) (void) Cloak_off();
    if(is_boots(otmp)) (void) Boots_off();
    if(is_helmet(otmp)) (void) Helmet_off();
    if(is_gloves(otmp)) (void) Gloves_off();
    if(is_shield(otmp)) (void) Shield_off();
    if(otmp == uarm) (void) Armor_gone();
    useup(otmp);
    break;
  }
  // ! 次の文は非常に複雑である
  // ! sの値は以下のようにして決まる
  // ! 巻物が呪われている場合は -1
  // ! 巻物が呪われていない場合, 
  // !  防具強化値が9以上の場合, 0〜防具強化値-1の一様乱数が0を取った場合1
  //                                                           取らない場合は0 
  // !  防具強化値が9より小さい場合
  // !   巻物が祝福されている場合, 1〜(3-防具強化値/3)の一様乱数
  // !   巻物が祝福されていない場合は 1
  s = sobj->cursed ? -1 :
    otmp->spe >= 9 ? (rn2(otmp->spe) == 0) :
    sobj->blessed ? rnd(3-otmp->spe/3) : 1;
  // ! ドラゴンの鱗の場合, ドラゴンの鱗鎧になるのだが, 関係ないので削除    
  // ! メッセージは重要な項目ではないのでコメント無し
  Your("%sは%s%s%s%s.",
       xname(otmp),
       (s*s>1) ? "しばらくの間" : "一瞬",
       s == 0 ? "激しく" : nul,
       Blind ? nul : 
       jconj_adj(hcolor(sobj->cursed ? NH_BLACK : NH_SILVER)),
       Blind ? "振動した" : "輝いた");
  // nethackでは, 巻物が呪われていると防具も呪われる
  otmp->cursed = sobj->cursed;
  // !nethackでは, 巻物が祝福されていると防具も祝福される
  if (!otmp->blessed || sobj->cursed)
    otmp->blessed = sobj->blessed;
  // !sの値分強化される      
  if (s) {
    otmp->spe += s;
    adj_abon(otmp, s);
    known = otmp->known;
  }

  // !エルフ防具ならば5より大きく強化されると必ず, 
  // !通常防具ならば3より大きく強化されると1/6の確率で, 振動する
  if ((otmp->spe > (special_armor ? 5 : 3)) &&
      (special_armor || !rn2(7)))
    Your("%sは突然%s振動した.",
	 xname(otmp),
	 Blind ? "また" : "思いもよらず");
  break;
}

/*
さて, 重要なのは
・蒸発するかどうかを決める部分
・今回の強化値を決めている部分
になる.

1. 蒸発するかどうかを決める部分
   これは簡単で, 強化値が3より大きい場合に, (強化値-1)/強化値の確率で蒸発する.
   即ち, +4ならば3/4, +5ならば4/5, ….
   これは強化値がいくつでも変わらない.
   エルフ防具の場合は5より大きい場合となっているので,
   +6ならば5/6, +7ならば6/7, ….
   となるが, 基本は通常防具と変わらない.
   蒸発するかしないかは, 巻物や防具の祝福, 呪いの如何に関わらない.
   ただし, 呪われている場合は正負が逆になる.
   即ち, 通常の防具の場合は-3より小さい場合に, 
   -(-強化値-1)/強化値の確率で蒸発する. 分かりにくいので例を示すと
   -4ならば3/4, -5ならば4/5 ….
   である. エルフ防具の場合は-5より小さい場合となる. 

2. 今回の強化値を決めている部分.
   こちらは少々複雑である. プログラムは効率よく(分かりにくく)かかれている
   が, ここでは巻物の祝福の如何別に書いてみる.
   2-1. 巻物が祝福も呪われもしていない場合.
        強化値が+9より小さければ絶対に+1である.
        強化値が+9以上の場合1/防具強化値の確率で+1になる.
                       (防具強化値-1)/防具強化値の確率で+0になる(強化されない).

	通常防具
        +0〜+3: 100% で+1
            +4: 25%  で+1           75%  で蒸発
            +5: 20%  で+1           80%  で蒸発
            +6: 16.6%で+1           83.3%で蒸発
            +7: 14.3%で+1           85.7%で蒸発
            +8: 12.5%で+1           87.5%で蒸発
            +9: 1.23%で+1 9.88%で+0 88.9%で蒸発  
           +10: 1%   で+1 9%   で+0 90%  で蒸発 
        エルフ防具など
        +0〜+5: 100% で+1
          +6〜: 通常防具と同じ

   2-2. 巻物が祝福されている場合
        強化値が+0〜+2の場合 +1〜+3の間でランダムに決まる
        強化値が+3〜+5の場合 +1〜+2の間でランダムに決まる
        強化値が+6〜+8の場合 必ず+1である
        強化値が+9以上の場合は, 2-1.と同様である.
        (ちなみに, -2〜+0の場合 +1〜+3の間でランダムに決まり,
                   -5〜-3の場合 +1〜+4の間でランダムに決まり…
         というように, 小さければ小さいほど大きい数字が出る可能性がある)
    
       通常防具
       +0〜+2: 33.3%で+1 33.3%で+2 33.3%で+3
           +3: 50%  で+1 50%  で+2
           +4: 12.5%で+1 12.5%で+2 75%で蒸発
           +5: 10%  で+1 10%  で+2 80%で蒸発   
         +6〜: 2-1.と同じ
       エルフ防具など
       +0〜+2: 33.3%で+1 33.3%で+2 33.3%で+3
       +3〜+5: 50%  で+1 50%で+2
         +6〜: 通常防具と同じ

   2-3. 巻物が呪われている場合
        強化値がいくつであろうと必ず-1になる.

       通常防具
        -3〜: 100% で-1
          -4: 25%  で-1   75%で蒸発
          -5: 20%  で-1   80%で蒸発
	  -6: 16.7%で-1 83.3%で蒸発
       エルフ防具
        -5〜: 100% で-1
        〜-6: 通常防具と同じ

考察
  前から言われているのと同様の結果となっていると思う.
  ただ, c-zelを貼る場合は通常防具で-6まで安全だという噂を聞いたことがある.
  これが事実だとすると今回の結果と反する.
  (通常の防具は-4までが安全である)

では次に武器の方にいってみよう
*/   

/* !read.cの1201行目〜1244行目 */
case SCR_ENCHANT_WEAPON:
// !混乱している時の処理ですが関係ない
if(uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))
   && confused) {
  // …ずーっと続いて…
} else return !chwepon(sobj,
		       sobj->cursed ? -1 :
		       !uwep ? 1 :
		       uwep->spe >= 9 ? (rn2(uwep->spe) == 0) :
		       sobj->blessed ? rnd(3-uwep->spe/3) : 1);
// ! 結局chweaponという関数が関係するようだが, 第2引数が重要そうなので
// ! 見てみよう
// ! 巻物が呪われている場合は -1
// ! 巻物が呪われていない場合
// !  装備している武器がなければ1
// !  武器強化値が9以上の場合, 0〜武器強化値-1の一様乱数が0なら1, それ以外は0
// !  武器強化値が9より小さい場合
// !   巻物が祝福されていれば, 1〜(3-武器強化値/3)の一様乱数
// !   巻物が祝福されていなければ 1
// ! これは防具の後半のsと同じ
break;

/* !wield.cの892行目〜1022行目 */
int
chwepon(otmp, amount)
  register struct obj *otmp;
register int amount;
{
  const char *color = hcolor((amount < 0) ? NH_BLACK : NH_BLUE);
  const char *xtime;
  int otyp = STRANGE_OBJECT;
  
  // ! 装備している武器がなかったり, 強化できないものだった場合の処理
  // ! 関係ないので削除

  // ! ワームの歯というもので, さらに強化値が0以上だったら
  // ! クリスナイフになるという処理だが全く関係ないので削除

  // ! クリスナイフで強化値が負だったらワームの歯に戻るという処理だが
  // ! やっぱり関係ないので削除

  // ! 強化値が負の場合, 武器がアーティファクトなら助かるという処理だが
  // ! 関係ないので削除

  /* there is a (soft) upper and lower limit to uwep->spe */
  /* ! 強化値には(柔らかい)上限と下限が存在する */
  // ! 「柔らかい」の意味するところは, OEに成功すれば超えられるという
  // ! ことだろうが, 失敗すると蒸発するので我々にとってはhardである ;-)

  // ! 武器強化値が5より大きく強化値が0より大きい
  // !   もしくは武器強化値が-5より小さく強化値が負,
  // ! かつ
  // !   0〜2の一様乱数が0以外を取った場合
  // ! 武器は蒸発する
  if(((uwep->spe > 5 && amount >= 0) || (uwep->spe < -5 && amount < 0))
     && rn2(3)) {
    if (!Blind)
    Your("%sはしばらく激しく%s輝き,蒸発した.",
	 xname(uwep), jconj_adj(color));
    else
      Your("%sは蒸発した.", xname(uwep));

    useupall(uwep);	/* let all of them disappear */
    return(1);
  }
  // ! メッセージは重要でないのでコメント無し 
  if (!Blind) {
    xtime = (amount*amount == 1) ? "一瞬" : "しばらくの間";
    Your("%sは%s%s%s輝いた.",
	 xname(uwep), xtime, jconj_adj(color), 
	 amount == 0 ? "激しく" : "");
    if (otyp != STRANGE_OBJECT && uwep->known &&
	(amount > 0 || (amount < 0 && otmp->bknown)))
      makeknown(otyp);
  }
  uwep->spe += amount;
  if(amount > 0) uwep->cursed = 0;

  // ! マジックベーンという特殊な武器に関する処理だが関係ないので削除

  // ! エルフの武器かアーティファクトの場合は5を超えると必ず,
  // ! 通常武器は5を超えると1/7の確率で, 振動する
  /* elven weapons vibrate warningly when enchanted beyond a limit */
  if ((uwep->spe > 5)
      && (is_elven_weapon(uwep) || uwep->oartifact || !rn2(7)))
  Your("%sは突然震えだした.",
       xname(uwep));

  return(1);
}

/*
武器の場合は, まずはじめに今回の強化値を決める.
この決め方は防具の方と全く同じである.
次に蒸発の条件をきめるが,
  強化値が+5より大きく今回の強化値が0以上の場合2/3の確率で蒸発する.
  強化値が-5より小さく今回の強化値が-1以下の場合は2/3の確率で蒸発する.
ということである. 即ち, 蒸発の確率は武器の強化値に依存しない.
しかしながら, 今回の強化値が0の場合でも2/3の確率で蒸発するため, 
+9の武器を強化するのは得策とは言えない.
巻物の祝福如何別に強化の確率を計算してみよう.

1. 巻物が祝福も呪われもされていない場合
     +0〜+5: 100%  で+1
     +6〜+8: 33.3% で+1           66.6%で蒸発
         +9: 3.7%  で+1 29.6%で+0 66.6%で蒸発 
        +10: 3.3%  で+1 30%で+0   66.6%で蒸発
        +11: 3.03% で+1 30.3%で+0 66.6%で蒸発
2. 巻物が祝福されている場合
     +0〜+2: 33.3% で+1 33.3%で+2 33.3%で+3 
     +3〜+5: 50%   で+1 50%  で+2
     +6〜:   1.と同じ
3. 巻物が呪われている場合
     -5〜: 100%で-1
     〜-6: 33.3%で-1 66.6%で蒸発

考察
  これも今まで考えられていたのと同じと言えるだろう.
  注目すべきは +9 以上の武器の強化は, それまでの強化値に依存するものの
  成功率はあまり変わらないということである.
  3%程度というのは余りにも低い確率ではあるが….
*/