/** * Test an ego item for any negative qualities */ bool good_ego(const ego_item_type * e_ptr) { int i, to_h, to_d; /* Resists, bonuses, multiples */ for (i = 0; i < MAX_P_RES; i++) if (e_ptr->percent_res[i] > RES_LEVEL_BASE) return FALSE; for (i = 0; i < A_MAX; i++) if (e_ptr->bonus_stat[i] < BONUS_BASE) return FALSE; for (i = 0; i < MAX_P_BONUS; i++) if (e_ptr->bonus_other[i] < BONUS_BASE) return FALSE; for (i = 0; i < MAX_P_SLAY; i++) if (e_ptr->multiple_slay[i] < MULTIPLE_BASE) return FALSE; for (i = 0; i < MAX_P_BRAND; i++) if (e_ptr->multiple_brand[i] < MULTIPLE_BASE) return FALSE; /* To skill, to deadliness, to AC */ if ((e_ptr->max_to_h > 0) && (e_ptr->max_to_h < 129)) to_h = e_ptr->max_to_h; else to_h = 128 - e_ptr->max_to_h; if ((e_ptr->max_to_d > 0) && (e_ptr->max_to_d < 129)) to_d = e_ptr->max_to_d; else to_d = 128 - e_ptr->max_to_d; if (to_h + to_d < 0) return FALSE; if (e_ptr->max_to_a > 128) return FALSE; /* Curses */ if (!cf_is_empty(e_ptr->flags_curse) || kf_has(e_ptr->flags_kind, KF_RAND_CURSE)) return FALSE; /* Must be OK */ return TRUE; }
/** * Browse known specialty abilities -BR- * Adapted from birth.c get_player_choice */ void view_specialties(void) { int i; /* Count the number of specialties we know */ for (i = 0, spec_known = 0; i < MAX_SPECIALTIES; i++) { if (p_ptr->specialty_order[i] != PF_NO_SPECIALTY) spec_list[spec_known++] = abilities[p_ptr->specialty_order[i]]; } /* Count the number of class powers we have */ for (i = 0; i < PF_MAX; i++) { if (player_class_has(i)) { spec_list[spec_known++] = abilities[i]; } } /* Count the number of race powers we have */ for (i = 0; i < PF_MAX; i++) { if (player_race_has(i)) { spec_list[spec_known++] = abilities[i]; } } /* Standard racial flags */ if (!of_is_empty(rp_ptr->flags_obj) || !cf_is_empty(rp_ptr->flags_curse)) { spec_list[spec_known].index = PF_MAX; spec_list[spec_known].name = ""; spec_list[spec_known].desc = ""; view_abilities_aux(race_other_desc); spec_list[spec_known++].type = PF_MAX; } /* View choices until user exits */ view_spec_menu(); /* exit */ return; }
/** * Attempt to change an object into an ego-item -MWK- * Better only called by apply_magic(). * The return value says if we picked a cursed item (if allowed) and is * passed on to a_m_aux1/2(). * If no legal ego item is found, this routine returns 0, resulting in * an unenchanted item. * * Modified for Oangband to specifically create cursed/non-cursed egos. * This is to keep the probabilities separate between cursed and * non-cursed ego types. */ static int make_ego_item(object_type * o_ptr, int power) { int i, j, level; int e_idx; long value, total; ego_item_type *e_ptr; alloc_entry *table = alloc_ego_table; /* Fail if object already is ego or artifact */ if (o_ptr->name1) return (FALSE); if (o_ptr->name2) return (FALSE); level = object_level; /* Boost level (like with object base types) */ if (level > 0) { /* Occasional "boost" */ if (randint0(GREAT_EGO) == 0) { /* The bizarre calculation again */ level = 1 + (level * MAX_DEPTH / randint1(MAX_DEPTH)); } } /* Reset total */ total = 0L; /* Process probabilities */ for (i = 0; i < alloc_ego_size; i++) { /* Default */ table[i].prob3 = 0; /* Objects are sorted by depth */ if (table[i].level > level) continue; /* Get the index */ e_idx = table[i].index; /* Get the actual kind */ e_ptr = &e_info[e_idx]; /* If we force good/great, don't create cursed */ if ((power > 0) && (!good_ego(e_ptr))) continue; /* If we force cursed, don't create good */ if ((power < 0) && good_ego(e_ptr)) continue; /* Test if this is a legal ego-item type for this object */ for (j = 0; j < EGO_TVALS_MAX; j++) { /* Require identical base type */ if (o_ptr->tval == e_ptr->tval[j]) { /* Require sval in bounds, lower */ if (o_ptr->sval >= e_ptr->min_sval[j]) { /* Require sval in bounds, upper */ if (o_ptr->sval <= e_ptr->max_sval[j]) { /* Accept */ table[i].prob3 = table[i].prob2; } } } } /* Total */ total += table[i].prob3; } /* No legal ego-items -- create a normal unenchanted one */ if (total == 0) return (0); /* Pick an ego-item */ value = randint0(total); /* Find the object */ for (i = 0; i < alloc_ego_size; i++) { /* Found the entry */ if (value < table[i].prob3) break; /* Decrement */ value = value - table[i].prob3; } /* We have one */ e_idx = (byte) table[i].index; o_ptr->name2 = e_idx; return ((!cf_is_empty(e_info[e_idx].flags_curse) || kf_has(e_info[e_idx].flags_kind, KF_RAND_CURSE)) ? -2 : 2); }