OSDN Git Service

Change Rarity of Armor ego.
[hengband/hengband.git] / src / object2.c
index 98f554d..c4a811c 100644 (file)
@@ -991,7 +991,12 @@ s32b flag_cost(object_type *o_ptr, int plusses)
        if (have_flag(flgs, TR_HIDE_TYPE)) total += 0;
        if (have_flag(flgs, TR_SHOW_MODS)) total += 0;
        if (have_flag(flgs, TR_LEVITATION)) total += 1250;
-       if (have_flag(flgs, TR_LITE)) total += 1250;
+       if (have_flag(flgs, TR_LITE_1)) total += 1500;
+       if (have_flag(flgs, TR_LITE_2)) total += 2500;
+       if (have_flag(flgs, TR_LITE_3)) total += 4000;
+       if (have_flag(flgs, TR_LITE_M1)) total -= 1500;
+       if (have_flag(flgs, TR_LITE_M2)) total -= 2500;
+       if (have_flag(flgs, TR_LITE_M3)) total -= 4000;
        if (have_flag(flgs, TR_SEE_INVIS)) total += 2000;
        if (have_flag(flgs, TR_TELEPATHY)) total += 20000;
        if (have_flag(flgs, TR_ESP_ANIMAL)) total += 1000;
@@ -1018,6 +1023,18 @@ s32b flag_cost(object_type *o_ptr, int plusses)
        if (have_flag(flgs, TR_IGNORE_COLD)) total += 100;
        if (have_flag(flgs, TR_ACTIVATE)) total += 100;
        if (have_flag(flgs, TR_DRAIN_EXP)) total -= 12500;
+       if (have_flag(flgs, TR_DRAIN_HP)) total -= 12500;
+       if (have_flag(flgs, TR_DRAIN_MANA)) total -= 12500;
+       if (have_flag(flgs, TR_CALL_ANIMAL)) total -= 12500;
+       if (have_flag(flgs, TR_CALL_DEMON)) total -= 10000;
+       if (have_flag(flgs, TR_CALL_DRAGON)) total -= 10000;
+       if (have_flag(flgs, TR_CALL_UNDEAD)) total -= 10000;
+       if (have_flag(flgs, TR_COWARDICE)) total -= 5000;
+       if (have_flag(flgs, TR_LOW_MELEE)) total -= 5000;
+       if (have_flag(flgs, TR_LOW_AC)) total -= 5000;
+       if (have_flag(flgs, TR_LOW_MAGIC)) total -= 15000;
+       if (have_flag(flgs, TR_FAST_DIGEST)) total -= 10000;
+       if (have_flag(flgs, TR_SLOW_REGEN)) total -= 10000;
        if (have_flag(flgs, TR_TELEPORT))
        {
                if (object_is_cursed(o_ptr))
@@ -1027,6 +1044,8 @@ s32b flag_cost(object_type *o_ptr, int plusses)
        }
        if (have_flag(flgs, TR_AGGRAVATE)) total -= 10000;
        if (have_flag(flgs, TR_BLESSED)) total += 750;
+       if (o_ptr->curse_flags & TR_ADD_L_CURSE) total -= 5000;
+       if (o_ptr->curse_flags & TR_ADD_H_CURSE) total -= 12500;
        if (o_ptr->curse_flags & TRC_CURSED) total -= 5000;
        if (o_ptr->curse_flags & TRC_HEAVY_CURSE) total -= 12500;
        if (o_ptr->curse_flags & TRC_PERMA_CURSE) total -= 15000;
@@ -1034,82 +1053,10 @@ s32b flag_cost(object_type *o_ptr, int plusses)
        /* Also, give some extra for activatable powers... */
        if (o_ptr->art_name && (have_flag(o_ptr->art_flags, TR_ACTIVATE)))
        {
-               int type = o_ptr->xtra2;
-
-               if (type == ACT_SUNLIGHT) total += 250;
-               else if (type == ACT_BO_MISS_1) total += 250;
-               else if (type == ACT_BA_POIS_1) total += 300;
-               else if (type == ACT_BO_ELEC_1) total += 250;
-               else if (type == ACT_BO_ACID_1) total += 250;
-               else if (type == ACT_BO_COLD_1) total += 250;
-               else if (type == ACT_BO_FIRE_1) total += 250;
-               else if (type == ACT_BA_COLD_1) total += 750;
-               else if (type == ACT_BA_FIRE_1) total += 1000;
-               else if (type == ACT_DRAIN_1) total += 500;
-               else if (type == ACT_BA_COLD_2) total += 1250;
-               else if (type == ACT_BA_ELEC_2) total += 1500;
-               else if (type == ACT_DRAIN_2) total += 750;
-               else if (type == ACT_VAMPIRE_1) total += 1000;
-               else if (type == ACT_BO_MISS_2) total += 1000;
-               else if (type == ACT_BA_FIRE_2) total += 1750;
-               else if (type == ACT_BA_COLD_3) total += 2500;
-               else if (type == ACT_BA_ELEC_3) total += 2500;
-               else if (type == ACT_WHIRLWIND) total += 7500;
-               else if (type == ACT_VAMPIRE_2) total += 2500;
-               else if (type == ACT_CALL_CHAOS) total += 5000;
-               else if (type == ACT_ROCKET) total += 5000;
-               else if (type == ACT_DISP_EVIL) total += 4000;
-               else if (type == ACT_DISP_GOOD) total += 3500;
-               else if (type == ACT_BA_MISS_3) total += 5000;
-               else if (type == ACT_CONFUSE) total += 500;
-               else if (type == ACT_SLEEP) total += 750;
-               else if (type == ACT_QUAKE) total += 600;
-               else if (type == ACT_TERROR) total += 2500;
-               else if (type == ACT_TELE_AWAY) total += 2000;
-               else if (type == ACT_BANISH_EVIL) total += 2000;
-               else if (type == ACT_GENOCIDE) total += 10000;
-               else if (type == ACT_MASS_GENO) total += 10000;
-               else if (type == ACT_CHARM_ANIMAL) total += 7500;
-               else if (type == ACT_CHARM_UNDEAD) total += 10000;
-               else if (type == ACT_CHARM_OTHER) total += 10000;
-               else if (type == ACT_CHARM_ANIMALS) total += 12500;
-               else if (type == ACT_CHARM_OTHERS) total += 17500;
-               else if (type == ACT_SUMMON_ANIMAL) total += 10000;
-               else if (type == ACT_SUMMON_PHANTOM) total += 12000;
-               else if (type == ACT_SUMMON_ELEMENTAL) total += 15000;
-               else if (type == ACT_SUMMON_DEMON) total += 20000;
-               else if (type == ACT_SUMMON_UNDEAD) total += 20000;
-               else if (type == ACT_CURE_LW) total += 500;
-               else if (type == ACT_CURE_MW) total += 750;
-               else if (type == ACT_CURE_POISON) total += 1000;
-               else if (type == ACT_REST_LIFE) total += 7500;
-               else if (type == ACT_REST_ALL) total += 15000;
-               else if (type == ACT_CURE_700) total += 10000;
-               else if (type == ACT_CURE_1000) total += 15000;
-               else if (type == ACT_ESP) total += 1500;
-               else if (type == ACT_BERSERK) total += 800;
-               else if (type == ACT_PROT_EVIL) total += 5000;
-               else if (type == ACT_RESIST_ALL) total += 5000;
-               else if (type == ACT_SPEED) total += 15000;
-               else if (type == ACT_XTRA_SPEED) total += 25000;
-               else if (type == ACT_WRAITH) total += 25000;
-               else if (type == ACT_INVULN) total += 25000;
-               else if (type == ACT_LIGHT) total += 150;
-               else if (type == ACT_MAP_LIGHT) total += 500;
-               else if (type == ACT_DETECT_ALL) total += 1000;
-               else if (type == ACT_DETECT_XTRA) total += 12500;
-               else if (type == ACT_ID_FULL) total += 10000;
-               else if (type == ACT_ID_PLAIN) total += 1250;
-               else if (type == ACT_RUNE_EXPLO) total += 4000;
-               else if (type == ACT_RUNE_PROT) total += 10000;
-               else if (type == ACT_SATIATE) total += 2000;
-               else if (type == ACT_DEST_DOOR) total += 100;
-               else if (type == ACT_STONE_MUD) total += 1000;
-               else if (type == ACT_RECHARGE) total += 1000;
-               else if (type == ACT_ALCHEMY) total += 10000;
-               else if (type == ACT_DIM_DOOR) total += 10000;
-               else if (type == ACT_TELEPORT) total += 2000;
-               else if (type == ACT_RECALL) total += 7500;
+               const activation_type* const act_ptr = find_activation_info(o_ptr);
+               if (act_ptr) {
+                       total += act_ptr->value;
+               }
        }
 
        return total;
@@ -1898,7 +1845,7 @@ void object_wipe(object_type *o_ptr)
 void object_copy(object_type *o_ptr, object_type *j_ptr)
 {
        /* Copy the structure */
-       COPY(o_ptr, j_ptr, object_type);
+       (void)COPY(o_ptr, j_ptr, object_type);
 }
 
 
@@ -1938,6 +1885,9 @@ void object_prep(object_type *o_ptr, int k_idx)
        o_ptr->dd = k_ptr->dd;
        o_ptr->ds = k_ptr->ds;
 
+       /* Default activation */
+       if (k_ptr->act_idx > 0) o_ptr->xtra2 = k_ptr->act_idx;
+
        /* Hack -- worthless items are always "broken" */
        if (k_info[o_ptr->k_idx].cost <= 0) o_ptr->ident |= (IDENT_BROKEN);
 
@@ -2385,6 +2335,8 @@ static void a_m_aux_1(object_type *o_ptr, int level, int power)
                                                continue;
                                        if (o_ptr->name2 == EGO_EARTHQUAKES && o_ptr->tval != TV_HAFTED)
                                                continue;
+                                       if (o_ptr->name2 == EGO_WEIRD && o_ptr->tval != TV_SWORD)
+                                               continue;
                                        break;
                                }
 
@@ -2462,6 +2414,21 @@ static void a_m_aux_1(object_type *o_ptr, int level, int power)
                                        if (one_in_(5))
                                                add_flag(o_ptr->art_flags, TR_SLAY_HUMAN);
                                        break;
+                               case EGO_DEMON:
+                                       
+                                       if(one_in_(3)) o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
+                                       one_in_(3) ? 
+                                               add_flag(o_ptr->art_flags, TR_DRAIN_EXP) :
+                                               one_in_(2) ?
+                                                       add_flag(o_ptr->art_flags, TR_DRAIN_HP) :
+                                                       add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
+                                               
+                                       
+                                       if (one_in_(3)) add_flag(o_ptr->art_flags, TR_CHAOTIC);
+                                       if (one_in_(4)) add_flag(o_ptr->art_flags, TR_BLOWS);
+                                       if (one_in_(5)) add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
+                                       if (one_in_(5)) add_flag(o_ptr->art_flags, TR_CALL_DEMON);
+                                       break;
                                }
 
                                if (!o_ptr->art_name)
@@ -2480,11 +2447,27 @@ static void a_m_aux_1(object_type *o_ptr, int level, int power)
                                /* Roll for ego-item */
                                if (randint0(MAX_DEPTH) < level)
                                {
-                                       o_ptr->name2 = get_random_ego(INVEN_RARM, FALSE);
+                                       while(1)
+                                       {
+                                               o_ptr->name2 = get_random_ego(INVEN_RARM, FALSE);
+                                               if (o_ptr->name2 == EGO_WEIRD && o_ptr->tval != TV_SWORD)
+                                               {
+                                                       continue;
+                                               }
+                                               break;
+                                       }
                                        switch (o_ptr->name2)
                                        {
                                        case EGO_MORGUL:
                                                if (one_in_(6)) add_flag(o_ptr->art_flags, TR_TY_CURSE);
+                                               if (one_in_(3)) o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
+                                       case EGO_WEIRD:
+                                               if (one_in_(4)) add_flag(o_ptr->art_flags, TR_BRAND_POIS);
+                                               if (one_in_(4)) add_flag(o_ptr->art_flags, TR_RES_NETHER);
+                                               if (one_in_(3)) add_flag(o_ptr->art_flags, TR_NO_MAGIC);
+                                               if (one_in_(6)) add_flag(o_ptr->art_flags, TR_NO_TELE);
+                                               if (one_in_(6)) add_flag(o_ptr->art_flags, TR_TY_CURSE);
+                                               if (one_in_(6)) add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
                                        }
                                }
                        }
@@ -2583,42 +2566,31 @@ static bool add_esp_strong(object_type *o_ptr)
 }
 
 
-#define MAX_ESP_WEAK 9
 static void add_esp_weak(object_type *o_ptr, bool extra)
 {
-       int i = 0;
-       int idx[MAX_ESP_WEAK];
-       int flg[MAX_ESP_WEAK];
-       int n = (extra) ? (3 + randint1(randint1(6))) : randint1(3);
-       int left = MAX_ESP_WEAK;
-
-       for (i = 0; i < MAX_ESP_WEAK; i++) flg[i] = i + 1;
+       int i;
+       u32b weak_esp_list[] = {
+               TR_ESP_ANIMAL,
+               TR_ESP_UNDEAD,
+               TR_ESP_DEMON,
+               TR_ESP_ORC,
+               TR_ESP_TROLL,
+               TR_ESP_GIANT,
+               TR_ESP_DRAGON,
+               TR_ESP_HUMAN,
+               TR_ESP_GOOD,
+               TR_ESP_UNIQUE,
+       };
+       const int MAX_ESP_WEAK = sizeof(weak_esp_list) / sizeof(weak_esp_list[0]);
+       const int add_count = MIN(MAX_ESP_WEAK, (extra) ? (3 + randint1(randint1(6))) : randint1(3));
 
-       /* Shuffle esp flags */
-       for (i = 0; i < n; i++)
+       /* Add unduplicated weak esp flags randomly */
+       for (i = 0; i < add_count; ++ i)
        {
-               int k = randint0(left--);
-
-               idx[i] = flg[k];
+               int choice = rand_range(i, MAX_ESP_WEAK - 1);
 
-               while (k < left)
-               {
-                       flg[k] = flg[k + 1];
-                       k++;
-               }
-       }
-
-       while (n--) switch (idx[n])
-       {
-       case 1: add_flag(o_ptr->art_flags, TR_ESP_ANIMAL); break;
-       case 2: add_flag(o_ptr->art_flags, TR_ESP_UNDEAD); break;
-       case 3: add_flag(o_ptr->art_flags, TR_ESP_DEMON); break;
-       case 4: add_flag(o_ptr->art_flags, TR_ESP_ORC); break;
-       case 5: add_flag(o_ptr->art_flags, TR_ESP_TROLL); break;
-       case 6: add_flag(o_ptr->art_flags, TR_ESP_GIANT); break;
-       case 7: add_flag(o_ptr->art_flags, TR_ESP_DRAGON);   break;
-       case 8: add_flag(o_ptr->art_flags, TR_ESP_HUMAN); break;
-       case 9: add_flag(o_ptr->art_flags, TR_ESP_GOOD); break;
+               add_flag(o_ptr->art_flags, weak_esp_list[choice]);
+               weak_esp_list[choice] = weak_esp_list[i];
        }
 }
 
@@ -2721,31 +2693,64 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
 
                                        switch (o_ptr->name2)
                                        {
-                                       case EGO_RESISTANCE:
-                                               if (one_in_(4))
-                                                       add_flag(o_ptr->art_flags, TR_RES_POIS);
-                                               break;
-                                       case EGO_ELVENKIND:
-                                               break;
-                                       case EGO_DWARVEN:
+                                         case EGO_DWARVEN:
                                                if (o_ptr->tval != TV_HARD_ARMOR)
                                                {
                                                        okay_flag = FALSE;
                                                        break;
                                                }
-                                               else
+                                         case EGO_DRUID:
+                                               if (o_ptr->tval != TV_SOFT_ARMOR)
                                                {
-                                                       o_ptr->weight = (2 * k_info[o_ptr->k_idx].weight / 3);
-                                                       o_ptr->ac = k_info[o_ptr->k_idx].ac + 5;
-                                                       if (one_in_(4))
-                                                               add_flag(o_ptr->art_flags, TR_CON);
+                                                       okay_flag = FALSE;
                                                        break;
                                                }
+                                         default:
+                                               break;
                                        }
 
                                        if (okay_flag)
                                                break;
                                }
+                               switch (o_ptr->name2)
+                               {
+                                 case EGO_RESISTANCE:
+                                       if (one_in_(4))
+                                               add_flag(o_ptr->art_flags, TR_RES_POIS);
+                                               break;
+                                 case EGO_DWARVEN:
+                                       o_ptr->weight = (2 * k_info[o_ptr->k_idx].weight / 3);
+                                       o_ptr->ac = k_info[o_ptr->k_idx].ac + 5;
+                                       break;
+                                       
+                                 case EGO_A_DEMON:
+                                       if(one_in_(3)) o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
+                                       one_in_(3) ? 
+                                               add_flag(o_ptr->art_flags, TR_DRAIN_EXP) :
+                                               one_in_(2) ?
+                                                       add_flag(o_ptr->art_flags, TR_DRAIN_HP) :
+                                                       add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
+                                               
+                                       if (one_in_(3)) add_flag(o_ptr->art_flags, TR_AGGRAVATE);
+                                       if (one_in_(3)) add_flag(o_ptr->art_flags, TR_ADD_L_CURSE);
+                                       if (one_in_(5)) add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
+                                       if (one_in_(5)) add_flag(o_ptr->art_flags, TR_DRAIN_HP);
+                                       if (one_in_(5)) add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
+                                       if (one_in_(5)) add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
+                                       if (one_in_(5)) add_flag(o_ptr->art_flags, TR_TY_CURSE);
+                                       if (one_in_(5)) add_flag(o_ptr->art_flags, TR_CALL_DEMON);
+                                       break;
+                                 case EGO_A_MORGUL:
+                                       if (one_in_(3)) o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
+                                       if (one_in_(9)) add_flag(o_ptr->art_flags, TR_TY_CURSE);
+                                       if (one_in_(4)) add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
+                                       if (one_in_(6)) add_flag(o_ptr->art_flags, TR_AGGRAVATE);
+                                       if (one_in_(9)) add_flag(o_ptr->art_flags, TR_NO_MAGIC);
+                                       if (one_in_(9)) add_flag(o_ptr->art_flags, TR_NO_TELE);
+                                       break;
+                                 default:
+                                       break;
+                               }
                        }
 
                        break;
@@ -2770,7 +2775,17 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
                                        create_artifact(o_ptr, FALSE);
                                        break;
                                }
-                               o_ptr->name2 = get_random_ego(INVEN_LARM, TRUE);
+                               
+                               while(1)
+                               {
+                                       o_ptr->name2 = get_random_ego(INVEN_LARM, TRUE);
+                                       if (o_ptr->sval != SV_SMALL_METAL_SHIELD && o_ptr->sval != SV_LARGE_METAL_SHIELD 
+                                                               && o_ptr->name2 == EGO_S_DWARVEN)
+                                       {
+                                               continue;
+                                       }
+                                       break;
+                               }
                                
                                switch (o_ptr->name2)
                                {
@@ -2782,6 +2797,11 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
                                        if (o_ptr->sval == SV_MIRROR_SHIELD)
                                                o_ptr->name2 = 0;
                                        break;
+                                       
+                               case EGO_S_DWARVEN:
+                                       o_ptr->weight = (2 * k_info[o_ptr->k_idx].weight / 3);
+                                       o_ptr->ac = k_info[o_ptr->k_idx].ac + 3;
+                                       break;
                                }
                        }
                        break;
@@ -2878,6 +2898,7 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
                                        case EGO_MIGHT:
                                        case EGO_REGENERATION:
                                        case EGO_LORDLINESS:
+                                       case EGO_BASILISK:
                                                break;
                                        case EGO_SEEING:
                                                if (one_in_(3))
@@ -2897,8 +2918,26 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
 
                        /* Very cursed */
                        else if (power < -1)
-                       {
-                               o_ptr->name2 = get_random_ego(INVEN_HEAD, FALSE);
+                       {       
+                               while (1)
+                               {
+                                       bool ok_flag = TRUE;
+                                       o_ptr->name2 = get_random_ego(INVEN_HEAD, FALSE);
+
+                                       switch (o_ptr->name2)
+                                       {
+                                         case EGO_ANCIENT_CURSE:
+                                               if (one_in_(3)) add_flag(o_ptr->art_flags, TR_NO_MAGIC);
+                                               if (one_in_(3)) add_flag(o_ptr->art_flags, TR_NO_TELE);
+                                               if (one_in_(3)) add_flag(o_ptr->art_flags, TR_TY_CURSE);
+                                               if (one_in_(3)) add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
+                                               if (one_in_(3)) add_flag(o_ptr->art_flags, TR_DRAIN_HP);
+                                               if (one_in_(3)) add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
+                                               break;
+                                       }
+                                       if (ok_flag)
+                                               break; /* while (1) */
+                               }
                        }
 
                        break;
@@ -2929,12 +2968,10 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
 
                                        switch (o_ptr->name2)
                                        {
-                                       case EGO_INTELLIGENCE:
-                                       case EGO_WISDOM:
-                                       case EGO_BEAUTY:
-                                       case EGO_LITE:
+                                       case EGO_BRILLIANCE:
                                        case EGO_DARK:
                                        case EGO_INFRAVISION:
+                                       case EGO_H_PROTECTION:
                                                break;
                                        case EGO_SEEING:
                                                if (one_in_(7))
@@ -2943,6 +2980,27 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
                                                        else add_esp_weak(o_ptr, FALSE);
                                                }
                                                break;
+                                       case EGO_LITE:
+                                               if (one_in_(3)) add_flag(o_ptr->art_flags, TR_LITE_1);
+                                               if (one_in_(3)) add_flag(o_ptr->art_flags, TR_LITE_2);
+                                               break;
+                                       case EGO_H_DEMON:
+                                               if(one_in_(3)) o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
+                                               one_in_(3) ? 
+                                                       add_flag(o_ptr->art_flags, TR_DRAIN_EXP) :
+                                                       one_in_(2) ?
+                                                               add_flag(o_ptr->art_flags, TR_DRAIN_HP) :
+                                                               add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
+                                               
+                                               if (one_in_(3)) add_flag(o_ptr->art_flags, TR_AGGRAVATE);
+                                               if (one_in_(3)) add_flag(o_ptr->art_flags, TR_ADD_L_CURSE);
+                                               if (one_in_(5)) add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
+                                               if (one_in_(5)) add_flag(o_ptr->art_flags, TR_DRAIN_HP);
+                                               if (one_in_(5)) add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
+                                               if (one_in_(5)) add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
+                                               if (one_in_(5)) add_flag(o_ptr->art_flags, TR_TY_CURSE);
+                                               if (one_in_(5)) add_flag(o_ptr->art_flags, TR_CALL_DEMON);
+                                               break;
                                        default:/* not existing helm (Magi, Might, etc...)*/
                                                ok_flag = FALSE;
                                        }
@@ -2954,7 +3012,19 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
                        /* Very cursed */
                        else if (power < -1)
                        {
-                               o_ptr->name2 = get_random_ego(INVEN_HEAD, FALSE);
+                               while (1)
+                               {
+                                       bool ok_flag = TRUE;
+                                       o_ptr->name2 = get_random_ego(INVEN_HEAD, FALSE);
+
+                                       switch (o_ptr->name2)
+                                       {
+                                         case EGO_ANCIENT_CURSE:
+                                               ok_flag = FALSE;
+                                       }
+                                       if (ok_flag)
+                                               break; /* while (1) */
+                               }
                        }
                        break;
                }
@@ -2977,6 +3047,14 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
                                        o_ptr->to_d -= 6;
                                        o_ptr->to_h -= 6;
                                        break;
+                                 case EGO_NAZGUL:
+                                       o_ptr->to_d -= 3;
+                                       o_ptr->to_h -= 3;
+                                       if (one_in_(3)) add_flag(o_ptr->art_flags, TR_COWARDICE);
+                                       if (one_in_(3)) add_flag(o_ptr->art_flags, TR_CALL_UNDEAD);
+                                       if (one_in_(3)) add_flag(o_ptr->art_flags, TR_SLOW_REGEN);
+                                       if (one_in_(3)) add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
+                                       break;
                                }
 
                        }
@@ -3322,7 +3400,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
                                                o_ptr->name2 = EGO_RING_REGEN;
                                                break;
                                        case 5: case 6:
-                                               if (have_flag(k_ptr->flags, TR_LITE)) break;
+                                               if (have_flag(k_ptr->flags, TR_LITE_1)) break;
                                                o_ptr->name2 = EGO_RING_LITE;
                                                break;
                                        case 7: case 8:
@@ -4244,6 +4322,7 @@ void apply_magic(object_type *o_ptr, int lev, u32b mode)
                o_ptr->to_h = a_ptr->to_h;
                o_ptr->to_d = a_ptr->to_d;
                o_ptr->weight = a_ptr->weight;
+               o_ptr->xtra2 = a_ptr->act_idx;
 
                /* Hack -- extract the "broken" flag */
                if (!a_ptr->cost) o_ptr->ident |= (IDENT_BROKEN);
@@ -4348,7 +4427,7 @@ void apply_magic(object_type *o_ptr, int lev, u32b mode)
        }
 
        /* Hack -- analyze ego-items */
-       else if (object_is_ego(o_ptr))
+       if (object_is_ego(o_ptr))
        {
                ego_item_type *e_ptr = &e_info[o_ptr->name2];
 
@@ -4370,9 +4449,22 @@ void apply_magic(object_type *o_ptr, int lev, u32b mode)
                if (e_ptr->gen_flags & (TRG_XTRA_D_RES)) one_dragon_ele_resistance(o_ptr);
                if (e_ptr->gen_flags & (TRG_XTRA_L_RES)) one_lordly_high_resistance(o_ptr);
                if (e_ptr->gen_flags & (TRG_XTRA_RES)) one_resistance(o_ptr);
+               if (e_ptr->gen_flags & (TRG_XTRA_DICE))
+               {
+                       do
+                       {
+                               o_ptr->dd++;
+                       }
+                       while (one_in_(o_ptr->dd));
+
+                       if (o_ptr->dd > 9) o_ptr->dd = 9;
+               }
+
+               /* Hack -- apply activatin index if needed */
+               if (e_ptr->act_idx) o_ptr->xtra2 = e_ptr->act_idx;
 
                /* Hack -- apply extra penalties if needed */
-               if (object_is_cursed(o_ptr) || object_is_broken(o_ptr))
+               if ((object_is_cursed(o_ptr) || object_is_broken(o_ptr)) && !(e_ptr->gen_flags & (TRG_POWERFUL)))
                {
                        /* Hack -- obtain bonuses */
                        if (e_ptr->max_to_h) o_ptr->to_h -= randint1(e_ptr->max_to_h);
@@ -4405,6 +4497,34 @@ void apply_magic(object_type *o_ptr, int lev, u32b mode)
                                        o_ptr->to_a -= randint1(256-e_ptr->max_to_a);
                                else o_ptr->to_a += randint1(e_ptr->max_to_a);
                        }
+                       
+                       /* Accuracy ego must have high to_h */
+                       if(o_ptr->name2 == EGO_ACCURACY)
+                       {
+                               while(o_ptr->to_h < o_ptr->to_d + 10)
+                               {
+                                       o_ptr->to_h += 5;
+                                       o_ptr->to_d -= 5;
+                               }
+                               o_ptr->to_h = MAX(o_ptr->to_h, 15);
+                       }
+                       
+                       /* Accuracy ego must have high to_h */
+                       if(o_ptr->name2 == EGO_VELOCITY)
+                       {
+                               while(o_ptr->to_d < o_ptr->to_h + 10)
+                               {
+                                       o_ptr->to_d += 5;
+                                       o_ptr->to_h -= 5;
+                               }
+                               o_ptr->to_d = MAX(o_ptr->to_d, 15);
+                       }
+                       
+                       /* Protection ego must have high to_a */
+                       if((o_ptr->name2 == EGO_PROTECTION) || (o_ptr->name2 == EGO_S_PROTECTION) || (o_ptr->name2 == EGO_H_PROTECTION))
+                       {
+                               o_ptr->to_a = MAX(o_ptr->to_a, 15);
+                       }
 
                        /* Hack -- obtain pval */
                        if (e_ptr->max_pval)
@@ -4414,6 +4534,17 @@ void apply_magic(object_type *o_ptr, int lev, u32b mode)
                                        o_ptr->pval++;
                                        if ((lev > 60) && one_in_(3) && ((o_ptr->dd*(o_ptr->ds+1)) < 15)) o_ptr->pval++;
                                }
+                               else if (o_ptr->name2 == EGO_DEMON)
+                               {
+                                       if(have_flag(o_ptr->art_flags, TR_BLOWS))
+                                       {
+                                               o_ptr->pval += randint1(2);
+                                       }
+                                       else
+                                       {
+                                               o_ptr->pval += randint1(e_ptr->max_pval);
+                                       }
+                               }
                                else if (o_ptr->name2 == EGO_ATTACKS)
                                {
                                        o_ptr->pval = randint1(e_ptr->max_pval*lev/100+1);
@@ -4426,10 +4557,16 @@ void apply_magic(object_type *o_ptr, int lev, u32b mode)
                                        o_ptr->pval = randint1(e_ptr->max_pval);
                                        if (o_ptr->sval == SV_ELVEN_CLOAK) o_ptr->pval += randint1(2);
                                }
+                               else if (o_ptr->name2 == EGO_A_DEMON || o_ptr->name2 == EGO_DRUID || o_ptr->name2 == EGO_OLOG)
+                               {
+                                       o_ptr->pval = randint1(e_ptr->max_pval);
+                               }
                                else
                                {
                                        o_ptr->pval += randint1(e_ptr->max_pval);
                                }
+                               
+                               
                        }
                        if ((o_ptr->name2 == EGO_SPEED) && (lev < 50))
                        {
@@ -4441,7 +4578,7 @@ void apply_magic(object_type *o_ptr, int lev, u32b mode)
 
                /* Cheat -- describe the item */
                if (cheat_peek) object_mention(o_ptr);
-
+               
                /* Done */
                return;
        }
@@ -4521,6 +4658,7 @@ static bool kind_is_good(int k_idx)
                case TV_CRUSADE_BOOK:
                case TV_MUSIC_BOOK:
                case TV_HISSATSU_BOOK:
+               case TV_HEX_BOOK:
                {
                        if (k_ptr->sval >= SV_BOOK_MIN_GOOD) return (TRUE);
                        return (FALSE);
@@ -5255,6 +5393,127 @@ void acquirement(int y1, int x1, int num, bool great, bool known)
 }
 
 
+/*
+ * Scatter some "amusing" objects near the player
+ */
+
+#define AMS_NOTHING   0x00 /* No restriction */
+#define AMS_NO_UNIQUE 0x01 /* Don't make the amusing object of uniques */
+#define AMS_FIXED_ART 0x02 /* Make a fixed artifact based on the amusing object */
+#define AMS_MULTIPLE  0x04 /* Drop 1-3 objects for one type */
+#define AMS_PILE      0x08 /* Drop 1-99 pile objects for one type */
+
+typedef struct
+{
+       int tval;
+       int sval;
+       int prob;
+       byte flag;
+} amuse_type;
+
+amuse_type amuse_info[] =
+{
+       { TV_BOTTLE, SV_ANY, 5, AMS_NOTHING },
+       { TV_JUNK, SV_ANY, 3, AMS_MULTIPLE },
+       { TV_SPIKE, SV_ANY, 10, AMS_PILE },
+       { TV_STATUE, SV_ANY, 15, AMS_NOTHING },
+       { TV_CORPSE, SV_ANY, 15, AMS_NO_UNIQUE },
+       { TV_SKELETON, SV_ANY, 10, AMS_NO_UNIQUE },
+       { TV_FIGURINE, SV_ANY, 10, AMS_NO_UNIQUE },
+       { TV_PARCHMENT, SV_ANY, 1, AMS_NOTHING },
+       { TV_POLEARM, SV_TSURIZAO, 3, AMS_NOTHING }, //Fishing Pole of Taikobo
+       { TV_SWORD, SV_BROKEN_DAGGER, 3, AMS_FIXED_ART }, //Broken Dagger of Magician
+       { TV_SWORD, SV_BROKEN_DAGGER, 10, AMS_NOTHING },
+       { TV_SWORD, SV_BROKEN_SWORD, 5, AMS_NOTHING },
+       { TV_SCROLL, SV_SCROLL_AMUSEMENT, 10, AMS_NOTHING },
+
+       { 0, 0, 0 }
+};
+
+void amusement(int y1, int x1, int num, bool known)
+{
+       object_type *i_ptr;
+       object_type object_type_body;
+       int n, t = 0;
+
+       for (n = 0; amuse_info[n].tval != 0; n++)
+       {
+               t += amuse_info[n].prob;
+       }
+
+       /* Acquirement */
+       while (num)
+       {
+               int i, k_idx, a_idx = 0;
+               int r = randint0(t);
+               bool insta_art, fixed_art;
+
+               for (i = 0; ; i++)
+               {
+                       r -= amuse_info[i].prob;
+                       if (r <= 0) break;
+               }
+
+               /* Get local object */
+               i_ptr = &object_type_body;
+
+               /* Wipe the object */
+               object_wipe(i_ptr);
+
+               /* Wipe the object */
+               k_idx = lookup_kind(amuse_info[i].tval, amuse_info[i].sval);
+
+               /* Paranoia - reroll if nothing */
+               if (!k_idx) continue;
+
+               /* Search an artifact index if need */
+               insta_art = (k_info[k_idx].gen_flags & TRG_INSTA_ART);
+               fixed_art = (amuse_info[i].flag & AMS_FIXED_ART);
+
+               if (insta_art || fixed_art)
+               {
+                       for (a_idx = 1; a_idx < max_a_idx; a_idx++)
+                       {
+                               if (insta_art && !(a_info[a_idx].gen_flags & TRG_INSTA_ART)) continue;
+                               if (a_info[a_idx].tval != k_info[k_idx].tval) continue;
+                               if (a_info[a_idx].sval != k_info[k_idx].sval) continue;
+                               if (a_info[a_idx].cur_num > 0) continue;
+                               break;
+                       }
+
+                       if (a_idx >= max_a_idx) continue;
+               }
+
+               /* Make an object (if possible) */
+               object_prep(i_ptr, k_idx);
+               if (a_idx) i_ptr->name1 = a_idx;
+               apply_magic(i_ptr, 1, AM_NO_FIXED_ART);
+
+               if (amuse_info[i].flag & AMS_NO_UNIQUE)
+               {
+                       if (r_info[i_ptr->pval].flags1 & RF1_UNIQUE) continue;
+               }
+
+               if (amuse_info[i].flag & AMS_MULTIPLE) i_ptr->number = randint1(3);
+               if (amuse_info[i].flag & AMS_PILE) i_ptr->number = randint1(99);
+
+               if (known)
+               {
+                       object_aware(i_ptr);
+                       object_known(i_ptr);
+               }
+
+               /* Paranoia - reroll if nothing */
+               if (!(i_ptr->k_idx)) continue;
+
+               /* Drop the object */
+               (void)drop_near(i_ptr, -1, y1, x1);
+
+               num--;
+       }
+}
+
+
 #define MAX_NORMAL_TRAPS 18
 
 /* See init_feat_variables() in init2.c */
@@ -5754,7 +6013,7 @@ bool object_sort_comp(object_type *o_ptr, s32b o_value, object_type *j_ptr)
        case TV_CAPTURE:
                if (r_info[o_ptr->pval].level < r_info[j_ptr->pval].level) return TRUE;
                if ((r_info[o_ptr->pval].level == r_info[j_ptr->pval].level) && (o_ptr->pval < j_ptr->pval)) return TRUE;
-               break;
+               return FALSE;
 
        case TV_SHOT:
        case TV_ARROW:
@@ -5892,8 +6151,8 @@ s16b inven_carry(object_type *o_ptr)
        /* Forget location */
        j_ptr->iy = j_ptr->ix = 0;
 
-       /* No longer marked */
-       j_ptr->marked = 0;
+       /* Player touches it, and no longer marked */
+       j_ptr->marked = OM_TOUCHED;
 
        /* Increase the weight */
        p_ptr->total_weight += (j_ptr->number * j_ptr->weight);
@@ -6817,7 +7076,7 @@ bool process_warning(int xx, int yy)
                        else strcpy(o_name, "body"); /* Warning ability without item */
                        msg_format("Your %s pulsates sharply!", o_name);
 #endif
-                       disturb(0, 0);
+                       disturb(0, 1);
 #ifdef JP
                        return get_check("ËÜÅö¤Ë¤³¤Î¤Þ¤Þ¿Ê¤à¤«¡©");
 #else
@@ -6841,7 +7100,7 @@ bool process_warning(int xx, int yy)
                else strcpy(o_name, "body"); /* Warning ability without item */
                msg_format("Your %s pulsates!", o_name);
 #endif
-               disturb(0, 0);
+               disturb(0, 1);
 #ifdef JP
                return get_check("ËÜÅö¤Ë¤³¤Î¤Þ¤Þ¿Ê¤à¤«¡©");
 #else
@@ -6950,7 +7209,7 @@ static essence_type essence_info[] =
        {TR_NO_MAGIC, "È¿ËâË¡", 3, TR_NO_MAGIC, 15},
        {TR_WARNING, "·Ù¹ð", 3, TR_WARNING, 20},
        {TR_LEVITATION, "ÉâÍ·", 3, TR_LEVITATION, 20},
-       {TR_LITE, "±Êµ×¸÷¸»", 3, TR_LITE, 15},
+       {TR_LITE_1, "±Êµ×¸÷¸»", 3, TR_LITE_1, 15},
        {TR_SEE_INVIS, "²Ä»ëÆ©ÌÀ", 3, TR_SEE_INVIS, 20},
        {TR_TELEPATHY, "¥Æ¥ì¥Ñ¥·¡¼", 6, TR_TELEPATHY, 15},
        {TR_SLOW_DIGEST, "Ãپò½", 3, TR_SLOW_DIGEST, 15},
@@ -7059,7 +7318,7 @@ static essence_type essence_info[] =
        {TR_NO_MAGIC, "anti magic", 3, TR_NO_MAGIC, 15},
        {TR_WARNING, "warning", 3, TR_WARNING, 20},
        {TR_LEVITATION, "levitation", 3, TR_LEVITATION, 20},
-       {TR_LITE, "permanent light", 3, TR_LITE, 15},
+       {TR_LITE_1, "permanent light", 3, TR_LITE_1, 15},
        {TR_SEE_INVIS, "see invisible", 3, TR_SEE_INVIS, 20},
        {TR_TELEPATHY, "telepathy", 6, TR_TELEPATHY, 15},
        {TR_SLOW_DIGEST, "slow digestion", 3, TR_SLOW_DIGEST, 15},
@@ -7358,7 +7617,7 @@ static void drain_essence(void)
        int i, item;
        int dec = 4;
        bool observe = FALSE;
-       int old_ds, old_dd, old_to_h, old_to_d, old_ac, old_to_a, old_pval, old_name2;
+       int old_ds, old_dd, old_to_h, old_to_d, old_ac, old_to_a, old_pval, old_name2, old_timeout;
        u32b old_flgs[TR_FLAG_SIZE], new_flgs[TR_FLAG_SIZE];
        object_type *o_ptr;
        cptr            q, s;
@@ -7426,12 +7685,27 @@ static void drain_essence(void)
        old_dd = o_ptr->dd;
        old_pval = o_ptr->pval;
        old_name2 = o_ptr->name2;
+       old_timeout = o_ptr->timeout;
        if (o_ptr->curse_flags & (TRC_CURSED | TRC_HEAVY_CURSE | TRC_PERMA_CURSE)) dec--;
+       if (have_flag(old_flgs, TR_ADD_L_CURSE)) dec--;
+       if (have_flag(old_flgs, TR_ADD_H_CURSE)) dec--;
        if (have_flag(old_flgs, TR_AGGRAVATE)) dec--;
        if (have_flag(old_flgs, TR_NO_TELE)) dec--;
        if (have_flag(old_flgs, TR_DRAIN_EXP)) dec--;
+       if (have_flag(old_flgs, TR_DRAIN_HP)) dec--;
+       if (have_flag(old_flgs, TR_DRAIN_MANA)) dec--;
+       if (have_flag(old_flgs, TR_CALL_ANIMAL)) dec--;
+       if (have_flag(old_flgs, TR_CALL_DEMON)) dec--;
+       if (have_flag(old_flgs, TR_CALL_DRAGON)) dec--;
+       if (have_flag(old_flgs, TR_CALL_UNDEAD)) dec--;
+       if (have_flag(old_flgs, TR_COWARDICE)) dec--;
+       if (have_flag(old_flgs, TR_LOW_MELEE)) dec--;
+       if (have_flag(old_flgs, TR_LOW_AC)) dec--;
+       if (have_flag(old_flgs, TR_LOW_MAGIC)) dec--;
+       if (have_flag(old_flgs, TR_FAST_DIGEST)) dec--;
+       if (have_flag(old_flgs, TR_SLOW_REGEN)) dec--;
        if (have_flag(old_flgs, TR_TY_CURSE)) dec--;
-
+       
        iy = o_ptr->iy;
        ix = o_ptr->ix;
        next_o_idx = o_ptr->next_o_idx;
@@ -7446,6 +7720,7 @@ static void drain_essence(void)
        o_ptr->next_o_idx=next_o_idx;
        o_ptr->marked=marked;
        o_ptr->number = number;
+       if (o_ptr->tval == TV_DRAG_ARMOR) o_ptr->timeout = old_timeout;
        if (item >= 0) p_ptr->total_weight += (o_ptr->weight*o_ptr->number - weight*number);
        o_ptr->ident |= (IDENT_MENTAL);
        object_aware(o_ptr);
@@ -7544,19 +7819,12 @@ static void drain_essence(void)
        }
        if (!observe)
        {
-#ifdef JP
-               msg_print("¥¨¥Ã¥»¥ó¥¹¤ÏÃê½Ð¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£");
-#else
-               msg_print("You were not able to extract any essence.");
-#endif
+               msg_print(_("¥¨¥Ã¥»¥ó¥¹¤ÏÃê½Ð¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", "You were not able to extract any essence."));
        }
        else
        {
-#ifdef JP
-               msg_print("Ãê½Ð¤·¤¿¥¨¥Ã¥»¥ó¥¹:");
-#else
-               msg_print("Extracted essences:");
-#endif
+               msg_print(_("Ãê½Ð¤·¤¿¥¨¥Ã¥»¥ó¥¹:", "Extracted essences:"));
+
                for (i = 0; essence_name[i]; i++)
                {
                        if (!essence_name[i][0]) continue;
@@ -7565,10 +7833,13 @@ static void drain_essence(void)
                        p_ptr->magic_num1[i] += drain_value[i];
                        p_ptr->magic_num1[i] = MIN(20000, p_ptr->magic_num1[i]);
                        msg_print(NULL);
-                       msg_format("%s...%d", essence_name[i], drain_value[i]);
+                       msg_format("%s...%d%s", essence_name[i], drain_value[i], _("¡£", ". "));
                }
        }
 
+       /* Apply autodestroy/inscription to the drained item */
+       autopick_alter_item(item, TRUE);
+
        /* Combine the pack */
        p_ptr->notice |= (PN_COMBINE | PN_REORDER);
 
@@ -8557,3 +8828,41 @@ void do_cmd_kaji(bool only_browse)
                case 5: add_essence(10);break;
        }
 }
+
+
+/*
+ * Torches have special abilities when they are flaming.
+ */
+void torch_flags(object_type *o_ptr, u32b *flgs)
+{
+       if ((o_ptr->tval == TV_LITE) && (o_ptr->sval == SV_LITE_TORCH))
+       {
+               if (o_ptr->xtra4 > 0)
+               {
+                       add_flag(flgs, TR_BRAND_FIRE);
+                       add_flag(flgs, TR_KILL_UNDEAD);
+                       add_flag(flgs, TR_THROW);
+               }
+       }
+}
+
+void torch_dice(object_type *o_ptr, int *dd, int *ds)
+{
+       if ((o_ptr->tval == TV_LITE) && (o_ptr->sval == SV_LITE_TORCH))
+       {
+               if (o_ptr->xtra4 > 0)
+               {
+                       (*dd) = 1;
+                       (*ds) = 6;
+               }
+       }
+}
+
+void torch_lost_fuel(object_type *o_ptr)
+{
+       if ((o_ptr->tval == TV_LITE) && (o_ptr->sval == SV_LITE_TORCH))
+       {
+               o_ptr->xtra4 -= (FUEL_TORCH / 25);
+               if (o_ptr->xtra4 < 0) o_ptr->xtra4 = 0;
+       }
+}