/src/object/randart.c
C | 3283 lines | 2280 code | 441 blank | 562 comment | 707 complexity | a2069a83996d7cacbdedc6489a21b7bb MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /*
- * File: randart.c
- * Purpose: Random artifact generation
- *
- * Copyright (c) 1998 Greg Wooledge, Ben Harrison, Robert Ruhlmann
- * Copyright (c) 2001 Chris Carr, Chris Robertson
- *
- * This work is free software; you can redistribute it and/or modify it
- * under the terms of either:
- *
- * a) the GNU General Public License as published by the Free Software
- * Foundation, version 2, or
- *
- * b) the "Angband licence":
- * This software may be copied and distributed for educational, research,
- * and not for profit purposes provided that this copyright and statement
- * are included in all such copies. Other copyrights may also apply.
- */
- #include "angband.h"
- #include "object/tvalsval.h"
- #include "init.h"
- #include "effects.h"
-
- /*
- * Original random artifact generator (randart) by Greg Wooledge.
- * Updated by Chris Carr / Chris Robertson 2001-2010.
- */
-
- #define MAX_TRIES 200
- #define BUFLEN 1024
-
- #define MIN_NAME_LEN 5
- #define MAX_NAME_LEN 9
- #define S_WORD 26
- #define E_WORD S_WORD
-
- /*
- * Inhibiting factors for large bonus values
- * "HIGH" values use INHIBIT_WEAK
- * "VERYHIGH" values use INHIBIT_STRONG
- */
- #define INHIBIT_STRONG (one_in_(6))
- #define INHIBIT_WEAK (one_in_(2))
-
- /*
- * Power rating below which uncursed randarts cannot aggravate
- * (so that aggravate is found only on endgame-quality items or
- * cursed items)
- */
- #define AGGR_POWER 300
-
- /*
- * Numerical index values for the different learned probabilities
- * These are to make the code more readable.
- * ToDo: turn these into an enum
- */
-
- #define ART_IDX_BOW_SHOTS 0
- #define ART_IDX_BOW_MIGHT 1
- #define ART_IDX_BOW_BRAND 80
- #define ART_IDX_BOW_SLAY 81
- #define ART_IDX_WEAPON_HIT 2
- #define ART_IDX_WEAPON_DAM 3
- #define ART_IDX_NONWEAPON_HIT 4
- #define ART_IDX_NONWEAPON_DAM 5
- #define ART_IDX_NONWEAPON_HIT_DAM 6
- #define ART_IDX_NONWEAPON_BRAND 78
- #define ART_IDX_NONWEAPON_SLAY 79
- #define ART_IDX_NONWEAPON_BLOWS 83
- #define ART_IDX_NONWEAPON_SHOTS 84
-
- #define ART_IDX_MELEE_BLESS 7
- #define ART_IDX_MELEE_BRAND 8
- #define ART_IDX_MELEE_SLAY 76
- #define ART_IDX_MELEE_SINV 9
- #define ART_IDX_MELEE_BLOWS 10
- #define ART_IDX_MELEE_AC 11
- #define ART_IDX_MELEE_DICE 12
- #define ART_IDX_MELEE_WEIGHT 13
- #define ART_IDX_MELEE_TUNN 14
-
- #define ART_IDX_ALLARMOR_WEIGHT 15
-
- #define ART_IDX_BOOT_AC 16
- #define ART_IDX_BOOT_FEATHER 17
- #define ART_IDX_BOOT_STEALTH 18
- #define ART_IDX_BOOT_SPEED 19
-
- #define ART_IDX_GLOVE_AC 20
- #define ART_IDX_GLOVE_FA 21
- #define ART_IDX_GLOVE_DEX 22
-
- #define ART_IDX_HELM_AC 23
- #define ART_IDX_HELM_RBLIND 24
- #define ART_IDX_HELM_ESP 25
- #define ART_IDX_HELM_SINV 26
- #define ART_IDX_HELM_WIS 27
- #define ART_IDX_HELM_INT 28
-
- #define ART_IDX_SHIELD_AC 29
- #define ART_IDX_SHIELD_LRES 30
-
- #define ART_IDX_CLOAK_AC 31
- #define ART_IDX_CLOAK_STEALTH 32
-
- #define ART_IDX_ARMOR_AC 33
- #define ART_IDX_ARMOR_STEALTH 34
- #define ART_IDX_ARMOR_HLIFE 35
- #define ART_IDX_ARMOR_CON 36
- #define ART_IDX_ARMOR_LRES 37
- #define ART_IDX_ARMOR_ALLRES 38
- #define ART_IDX_ARMOR_HRES 39
-
- #define ART_IDX_GEN_STAT 40
- #define ART_IDX_GEN_SUST 41
- #define ART_IDX_GEN_STEALTH 42
- #define ART_IDX_GEN_SEARCH 43
- #define ART_IDX_GEN_INFRA 44
- #define ART_IDX_GEN_SPEED 45
- #define ART_IDX_GEN_IMMUNE 46
- #define ART_IDX_GEN_FA 47
- #define ART_IDX_GEN_HLIFE 48
- #define ART_IDX_GEN_FEATHER 49
- #define ART_IDX_GEN_LIGHT 50
- #define ART_IDX_GEN_SINV 51
- #define ART_IDX_GEN_ESP 52
- #define ART_IDX_GEN_SDIG 53
- #define ART_IDX_GEN_REGEN 54
- #define ART_IDX_GEN_LRES 55
- #define ART_IDX_GEN_RPOIS 56
- #define ART_IDX_GEN_RFEAR 57
- #define ART_IDX_GEN_RLIGHT 58
- #define ART_IDX_GEN_RDARK 59
- #define ART_IDX_GEN_RBLIND 60
- #define ART_IDX_GEN_RCONF 61
- #define ART_IDX_GEN_RSOUND 62
- #define ART_IDX_GEN_RSHARD 63
- #define ART_IDX_GEN_RNEXUS 64
- #define ART_IDX_GEN_RNETHER 65
- #define ART_IDX_GEN_RCHAOS 66
- #define ART_IDX_GEN_RDISEN 67
- #define ART_IDX_GEN_AC 68
- #define ART_IDX_GEN_TUNN 69
- #define ART_IDX_GEN_ACTIV 82
-
- /* Supercharged abilities - treated differently in algorithm */
-
- #define ART_IDX_MELEE_DICE_SUPER 70
- #define ART_IDX_BOW_SHOTS_SUPER 71
- #define ART_IDX_BOW_MIGHT_SUPER 72
- #define ART_IDX_GEN_SPEED_SUPER 73
- #define ART_IDX_MELEE_BLOWS_SUPER 77
- #define ART_IDX_GEN_AC_SUPER 85
-
- /* Aggravation - weapon and nonweapon */
- #define ART_IDX_WEAPON_AGGR 74
- #define ART_IDX_NONWEAPON_AGGR 75
-
- /* Total of abilities */
- #define ART_IDX_TOTAL 86
-
- /* Tallies of different ability types */
- /* ToDo: use N_ELEMENTS for these */
- #define ART_IDX_BOW_COUNT 4
- #define ART_IDX_WEAPON_COUNT 3
- #define ART_IDX_NONWEAPON_COUNT 8
- #define ART_IDX_MELEE_COUNT 9
- #define ART_IDX_ALLARMOR_COUNT 1
- #define ART_IDX_BOOT_COUNT 4
- #define ART_IDX_GLOVE_COUNT 3
- #define ART_IDX_HELM_COUNT 6
- #define ART_IDX_SHIELD_COUNT 2
- #define ART_IDX_CLOAK_COUNT 2
- #define ART_IDX_ARMOR_COUNT 7
- #define ART_IDX_GEN_COUNT 31
- #define ART_IDX_HIGH_RESIST_COUNT 12
-
- /* Arrays of indices by item type, used in frequency generation */
- static s16b art_idx_bow[] =
- {ART_IDX_BOW_SHOTS, ART_IDX_BOW_MIGHT, ART_IDX_BOW_BRAND, ART_IDX_BOW_SLAY};
- static s16b art_idx_weapon[] =
- {ART_IDX_WEAPON_HIT, ART_IDX_WEAPON_DAM, ART_IDX_WEAPON_AGGR};
- static s16b art_idx_nonweapon[] =
- {ART_IDX_NONWEAPON_HIT, ART_IDX_NONWEAPON_DAM, ART_IDX_NONWEAPON_HIT_DAM,
- ART_IDX_NONWEAPON_AGGR, ART_IDX_NONWEAPON_BRAND, ART_IDX_NONWEAPON_SLAY,
- ART_IDX_NONWEAPON_BLOWS, ART_IDX_NONWEAPON_SHOTS};
- static s16b art_idx_melee[] =
- {ART_IDX_MELEE_BLESS, ART_IDX_MELEE_SINV, ART_IDX_MELEE_BRAND, ART_IDX_MELEE_SLAY,
- ART_IDX_MELEE_BLOWS, ART_IDX_MELEE_AC, ART_IDX_MELEE_DICE,
- ART_IDX_MELEE_WEIGHT, ART_IDX_MELEE_TUNN};
- static s16b art_idx_allarmor[] =
- {ART_IDX_ALLARMOR_WEIGHT};
- static s16b art_idx_boot[] =
- {ART_IDX_BOOT_AC, ART_IDX_BOOT_FEATHER, ART_IDX_BOOT_STEALTH, ART_IDX_BOOT_SPEED};
- static s16b art_idx_glove[] =
- {ART_IDX_GLOVE_AC, ART_IDX_GLOVE_FA, ART_IDX_GLOVE_DEX};
- static s16b art_idx_headgear[] =
- {ART_IDX_HELM_AC, ART_IDX_HELM_RBLIND, ART_IDX_HELM_ESP, ART_IDX_HELM_SINV,
- ART_IDX_HELM_WIS, ART_IDX_HELM_INT};
- static s16b art_idx_shield[] =
- {ART_IDX_SHIELD_AC, ART_IDX_SHIELD_LRES};
- static s16b art_idx_cloak[] =
- {ART_IDX_CLOAK_AC, ART_IDX_CLOAK_STEALTH};
- static s16b art_idx_armor[] =
- {ART_IDX_ARMOR_AC, ART_IDX_ARMOR_STEALTH, ART_IDX_ARMOR_HLIFE, ART_IDX_ARMOR_CON,
- ART_IDX_ARMOR_LRES, ART_IDX_ARMOR_ALLRES, ART_IDX_ARMOR_HRES};
- static s16b art_idx_gen[] =
- {ART_IDX_GEN_STAT, ART_IDX_GEN_SUST, ART_IDX_GEN_STEALTH,
- ART_IDX_GEN_SEARCH, ART_IDX_GEN_INFRA, ART_IDX_GEN_SPEED,
- ART_IDX_GEN_IMMUNE, ART_IDX_GEN_FA, ART_IDX_GEN_HLIFE,
- ART_IDX_GEN_FEATHER, ART_IDX_GEN_LIGHT, ART_IDX_GEN_SINV,
- ART_IDX_GEN_ESP, ART_IDX_GEN_SDIG, ART_IDX_GEN_REGEN,
- ART_IDX_GEN_LRES, ART_IDX_GEN_RPOIS, ART_IDX_GEN_RFEAR,
- ART_IDX_GEN_RLIGHT, ART_IDX_GEN_RDARK, ART_IDX_GEN_RBLIND,
- ART_IDX_GEN_RCONF, ART_IDX_GEN_RSOUND, ART_IDX_GEN_RSHARD,
- ART_IDX_GEN_RNEXUS, ART_IDX_GEN_RNETHER, ART_IDX_GEN_RCHAOS,
- ART_IDX_GEN_RDISEN, ART_IDX_GEN_AC, ART_IDX_GEN_TUNN,
- ART_IDX_GEN_ACTIV};
- static s16b art_idx_high_resist[] =
- {ART_IDX_GEN_RPOIS, ART_IDX_GEN_RFEAR,
- ART_IDX_GEN_RLIGHT, ART_IDX_GEN_RDARK, ART_IDX_GEN_RBLIND,
- ART_IDX_GEN_RCONF, ART_IDX_GEN_RSOUND, ART_IDX_GEN_RSHARD,
- ART_IDX_GEN_RNEXUS, ART_IDX_GEN_RNETHER, ART_IDX_GEN_RCHAOS,
- ART_IDX_GEN_RDISEN};
-
- /* Initialize the data structures for learned probabilities */
- static s16b artprobs[ART_IDX_TOTAL];
- s16b *baseprobs;
- static s16b art_bow_total = 0;
- static s16b art_melee_total = 0;
- static s16b art_boot_total = 0;
- static s16b art_glove_total = 0;
- static s16b art_headgear_total = 0;
- static s16b art_shield_total = 0;
- static s16b art_cloak_total = 0;
- static s16b art_armor_total = 0;
- static s16b art_other_total = 0;
- static s16b art_total = 0;
-
- /*
- * Working arrays for holding frequency values - global to avoid repeated
- * allocation of memory
- */
- static s16b art_freq[ART_IDX_TOTAL]; /* artifact attributes */
- s16b *base_freq; /* base items */
-
- /*
- * Mean start and increment values for to_hit, to_dam and AC. Update these
- * if the algorithm changes. They are used in frequency generation.
- */
- static s16b mean_hit_increment = 4;
- static s16b mean_dam_increment = 4;
- static s16b mean_hit_startval = 10;
- static s16b mean_dam_startval = 10;
- static s16b mean_ac_startval = 15;
- static s16b mean_ac_increment = 5;
-
- /*
- * Pointer for logging file
- */
- static ang_file *log_file = NULL;
-
- /*
- * Store the original artifact power ratings
- */
- static s32b *base_power;
- static s16b max_power;
- static s16b min_power;
- static s16b avg_power;
- static s16b var_power;
-
- /*
- * Store the original base item levels
- */
- static byte *base_item_level;
-
- /*
- * Store the original base item rarities
- */
- static byte *base_item_prob;
-
- /*
- * Store the original artifact rarities
- */
- static byte *base_art_alloc;
-
- /* Global just for convenience. */
- static int verbose = 1;
-
- /*
- * Object flag names
- */
- static const char *flag_names[] =
- {
- #define OF(a, b) #a,
- #include "list-object-flags.h"
- #undef OF
- ""
- };
-
- /*
- * Use W. Sheldon Simms' random name generator.
- */
- static errr init_names(void)
- {
- char buf[BUFLEN];
- size_t name_size;
- char *a_base;
- char *a_next;
- int i;
-
- /* Temporary space for names, while reading and randomizing them. */
- char **names;
-
- /* Allocate the "names" array */
- /* ToDo: Make sure the memory is freed correctly in case of errors */
- names = C_ZNEW(z_info->a_max, char *);
-
- for (i = 0; i < z_info->a_max; i++)
- {
- char word[MAX_NAME_LEN + 1];
- randname_make(RANDNAME_TOLKIEN, MIN_NAME_LEN, MAX_NAME_LEN,
- word, sizeof word);
- word[0] = toupper((unsigned char) word[0]);
-
- if (one_in_(3))
- strnfmt(buf, sizeof(buf), "'%s'", word);
- else
- strnfmt(buf, sizeof(buf), "of %s", word);
-
- names[i] = string_make(buf);
- }
-
- /* Special cases -- keep these three names separate. */
- string_free(names[ART_POWER - 1]);
- string_free(names[ART_GROND - 1]);
- string_free(names[ART_MORGOTH - 1]);
- names[ART_POWER - 1] = string_make("of Power (The One Ring)");
- names[ART_GROND - 1] = string_make("'Grond'");
- names[ART_MORGOTH - 1] = string_make("of Morgoth");
-
- /* Convert our names array into an a_name structure for later use. */
- name_size = 0;
-
- for (i = 1; i < z_info->a_max; i++)
- {
- name_size += strlen(names[i-1]) + 2; /* skip first char */
- }
-
- a_base = C_ZNEW(name_size, char);
-
- a_next = a_base + 1; /* skip first char */
-
- for (i = 1; i < z_info->a_max; i++)
- {
- my_strcpy(a_next, names[i-1], name_size - 1);
- if (a_info[i].tval > 0) /* skip unused! */
- a_info[i].name = a_next - a_base;
- a_next += strlen(names[i-1]) + 1;
- }
-
- /* Free the old names */
- FREE(a_name);
-
- for (i = 0; i < z_info->a_max; i++)
- {
- string_free(names[i]);
- }
-
- /* Free the "names" array */
- FREE(names);
-
- /* Store the names */
- a_name = a_base;
- a_head.name_ptr = a_base;
- a_head.name_size = name_size;
-
- /* Success */
- return (0);
- }
-
- /*
- * Return the artifact power, by generating a "fake" object based on the
- * artifact, and calling the common object_power function
- */
- static s32b artifact_power(int a_idx)
- {
- object_type obj;
-
- LOG_PRINT("********** ENTERING EVAL POWER ********\n");
- LOG_PRINT1("Artifact index is %d\n", a_idx);
-
- if(!make_fake_artifact(&obj, a_idx))
- {
- return 0;
- }
-
- return object_power(&obj, verbose, log_file, TRUE);
- }
-
-
- /*
- * Store the original artifact power ratings as a baseline
- */
- static void store_base_power (void)
- {
- int i, j;
- artifact_type *a_ptr;
- object_kind *k_ptr;
- s16b k_idx;
- int *fake_power;
-
- max_power = 0;
- min_power = 32767;
- var_power = 0;
- fake_power = C_ZNEW(z_info->a_max, int);
- j = 0;
-
- for(i = 0; i < z_info->a_max; i++, j++)
- {
- base_power[i] = artifact_power(i);
-
- /* capture power stats, ignoring cursed and uber arts */
- if (base_power[i] > max_power && base_power[i] < INHIBIT_POWER)
- max_power = base_power[i];
- if (base_power[i] < min_power && base_power[i] > 0)
- min_power = base_power[i];
- if (base_power[i] > 0 && base_power[i] < INHIBIT_POWER)
- fake_power[j] = (int)base_power[i];
- else
- j--;
-
- a_ptr = &a_info[i];
- k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
- k_ptr = &k_info[k_idx];
- base_item_level[i] = k_ptr->level;
- base_item_prob[i] = k_ptr->alloc_prob;
- base_art_alloc[i] = a_ptr->alloc_prob;
- }
-
- avg_power = mean(fake_power, j);
- var_power = variance(fake_power, j);
-
- LOG_PRINT2("Max power is %d, min is %d\n", max_power, min_power);
- LOG_PRINT2("Mean is %d, variance is %d\n", avg_power, var_power);
-
- /* Store the number of different types, for use later */
- /* ToDo: replace this with full combination tracking */
- for (i = 0; i < z_info->a_max; i++)
- {
- switch (a_info[i].tval)
- {
- case TV_SWORD:
- case TV_POLEARM:
- case TV_HAFTED:
- art_melee_total++; break;
- case TV_BOW:
- art_bow_total++; break;
- case TV_SOFT_ARMOR:
- case TV_HARD_ARMOR:
- case TV_DRAG_ARMOR:
- art_armor_total++; break;
- case TV_SHIELD:
- art_shield_total++; break;
- case TV_CLOAK:
- art_cloak_total++; break;
- case TV_HELM:
- case TV_CROWN:
- art_headgear_total++; break;
- case TV_GLOVES:
- art_glove_total++; break;
- case TV_BOOTS:
- art_boot_total++; break;
- default:
- art_other_total++;
- }
- }
- art_total = art_melee_total + art_bow_total + art_armor_total +
- art_shield_total + art_cloak_total + art_headgear_total +
- art_glove_total + art_boot_total + art_other_total;
- }
-
-
- /*
- * Randomly select a base item type (tval,sval). Assign the various fields
- * corresponding to that choice.
- *
- * The return value gives the index of the new item type. The method is
- * passed a pointer to a rarity value in order to return the rarity of the
- * new item.
- */
- static s16b choose_item(int a_idx)
- {
- artifact_type *a_ptr = &a_info[a_idx];
- int tval = 0;
- int sval = 0;
- object_kind *k_ptr;
- int i;
- s16b k_idx, r;
-
- /*
- * Pick a base item from the cumulative frequency table.
- *
- * Although this looks hideous, it provides for easy addition of
- * future artifact types, simply by removing the tvals from this
- * loop.
- *
- * N.B. Could easily generate lights, rings and amulets this way if
- * the whole special/flavour issue was sorted out (see ticket #1014)
- * Note that Carlammas and Barahir have the same sval as Grond/Morgoth
- */
- while (tval == 0 || tval == TV_SKELETON || tval == TV_BOTTLE ||
- tval == TV_JUNK || tval == TV_SPIKE || tval == TV_CHEST ||
- tval == TV_SHOT || tval == TV_ARROW || tval == TV_BOLT ||
- tval == TV_STAFF || tval == TV_WAND || tval == TV_ROD ||
- tval == TV_SCROLL || tval == TV_POTION || tval == TV_FLASK ||
- tval == TV_FOOD || tval == TV_MAGIC_BOOK || tval ==
- TV_PRAYER_BOOK || tval == TV_GOLD || tval == TV_LIGHT ||
- tval == TV_AMULET || tval == TV_RING || sval == SV_GROND ||
- sval == SV_MORGOTH)
- {
- r = randint1(base_freq[z_info->k_max - 1]);
- i = 0;
- while (r > base_freq[i])
- {
- i++;
- }
- tval = k_info[i].tval;
- sval = k_info[i].sval;
- }
- LOG_PRINT2("Creating tval %d sval %d\n", tval, sval);
- k_idx = lookup_kind(tval, sval);
- k_ptr = &k_info[k_idx];
- a_ptr->tval = k_ptr->tval;
- a_ptr->sval = k_ptr->sval;
- a_ptr->pval = randcalc(k_ptr->pval, 0, MINIMISE);
- a_ptr->to_h = randcalc(k_ptr->to_h, 0, MINIMISE);
- a_ptr->to_d = randcalc(k_ptr->to_d, 0, MINIMISE);
- a_ptr->to_a = randcalc(k_ptr->to_a, 0, MINIMISE);
- a_ptr->ac = k_ptr->ac;
- a_ptr->dd = k_ptr->dd;
- a_ptr->ds = k_ptr->ds;
- a_ptr->weight = k_ptr->weight;
- of_copy(a_ptr->flags, k_ptr->flags);
- a_ptr->effect = 0;
-
- /* Artifacts ignore everything */
- flags_set(a_ptr->flags, OF_SIZE, OF_IGNORE_MASK, FLAG_END);
-
- /* Assign basic stats to the artifact based on its artifact level. */
- /*
- * CR, 2001-09-03: changed to a simpler version to match the hit-dam
- * parsing algorithm. We use random ranges averaging mean_hit_startval
- * and mean_dam_startval, but permitting variation of 50% to 150%.
- * Level-dependent term has been removed for the moment.
- */
- switch (a_ptr->tval)
- {
- case TV_BOW:
- case TV_DIGGING:
- case TV_HAFTED:
- case TV_SWORD:
- case TV_POLEARM:
- a_ptr->to_h += (s16b)(mean_hit_startval / 2 +
- randint0(mean_hit_startval) );
- a_ptr->to_d += (s16b)(mean_dam_startval / 2 +
- randint0(mean_dam_startval) );
- LOG_PRINT2("Assigned basic stats, to_hit: %d, to_dam: %d\n", a_ptr->to_h, a_ptr->to_d);
- break;
- case TV_BOOTS:
- case TV_GLOVES:
- case TV_HELM:
- case TV_CROWN:
- case TV_SHIELD:
- case TV_CLOAK:
- case TV_SOFT_ARMOR:
- case TV_HARD_ARMOR:
- case TV_DRAG_ARMOR:
- /* CR: adjusted this to work with parsing logic */
- a_ptr->to_a += (s16b)(mean_ac_startval / 2 +
- randint0(mean_ac_startval) );
- LOG_PRINT1("Assigned basic stats, AC bonus: %d\n", a_ptr->to_a);
- break;
- }
-
- /* Done - return the index of the new object kind. */
- return k_idx;
- }
-
-
- /*
- * We've just added an ability which uses the pval bonus. Make sure it's
- * not zero. If it's currently negative, leave it negative (heh heh).
- */
- static void do_pval(artifact_type *a_ptr)
- {
- int factor = 1;
-
- /* Track whether we have blows, might or shots on this item */
- if (of_has(a_ptr->flags, OF_BLOWS)) factor++;
- if (of_has(a_ptr->flags, OF_MIGHT)) factor++;
- if (of_has(a_ptr->flags, OF_SHOTS)) factor++;
-
- if (a_ptr->pval == 0)
- {
- /* Blows, might, shots handled separately */
- if (factor > 1)
- {
- a_ptr->pval = (s16b)randint1(2);
- /* Give it a shot at +3 */
- if (INHIBIT_STRONG) a_ptr->pval = 3;
- }
- else a_ptr->pval = (s16b)randint1(4);
- LOG_PRINT1("Assigned initial pval, value is: %d\n", a_ptr->pval);
- }
- else if (a_ptr->pval < 0)
- {
- if (one_in_(2))
- {
- a_ptr->pval--;
- LOG_PRINT1("Decreasing pval by 1, new value is: %d\n", a_ptr->pval);
- }
- }
- else if (one_in_(a_ptr->pval * factor))
- {
- /*
- * CR: made this a bit rarer and diminishing with higher pval -
- * also rarer if item has blows/might/shots already
- */
- a_ptr->pval++;
- LOG_PRINT1("Increasing pval by 1, new value is: %d\n", a_ptr->pval);
- }
- }
-
-
- static void remove_contradictory(artifact_type *a_ptr)
- {
- if (of_has(a_ptr->flags, OF_AGGRAVATE)) of_off(a_ptr->flags, OF_STEALTH);
- if (of_has(a_ptr->flags, OF_IM_ACID)) of_off(a_ptr->flags, OF_RES_ACID);
- if (of_has(a_ptr->flags, OF_IM_ELEC)) of_off(a_ptr->flags, OF_RES_ELEC);
- if (of_has(a_ptr->flags, OF_IM_FIRE)) of_off(a_ptr->flags, OF_RES_FIRE);
- if (of_has(a_ptr->flags, OF_IM_COLD)) of_off(a_ptr->flags, OF_RES_COLD);
-
- if (a_ptr->pval < 0)
- {
- if (of_has(a_ptr->flags, OF_STR)) of_off(a_ptr->flags, OF_SUST_STR);
- if (of_has(a_ptr->flags, OF_INT)) of_off(a_ptr->flags, OF_SUST_INT);
- if (of_has(a_ptr->flags, OF_WIS)) of_off(a_ptr->flags, OF_SUST_WIS);
- if (of_has(a_ptr->flags, OF_DEX)) of_off(a_ptr->flags, OF_SUST_DEX);
- if (of_has(a_ptr->flags, OF_CON)) of_off(a_ptr->flags, OF_SUST_CON);
- if (of_has(a_ptr->flags, OF_CHR)) of_off(a_ptr->flags, OF_SUST_CHR);
- of_off(a_ptr->flags, OF_BLOWS);
- }
-
- if (of_has(a_ptr->flags, OF_LIGHT_CURSE)) of_off(a_ptr->flags, OF_BLESSED);
- if (of_has(a_ptr->flags, OF_KILL_DRAGON)) of_off(a_ptr->flags, OF_SLAY_DRAGON);
- if (of_has(a_ptr->flags, OF_KILL_DEMON)) of_off(a_ptr->flags, OF_SLAY_DEMON);
- if (of_has(a_ptr->flags, OF_KILL_UNDEAD)) of_off(a_ptr->flags, OF_SLAY_UNDEAD);
- if (of_has(a_ptr->flags, OF_DRAIN_EXP)) of_off(a_ptr->flags, OF_HOLD_LIFE);
- }
-
- /*
- * Adjust the parsed frequencies for any peculiarities of the
- * algorithm. For example, if stat bonuses and sustains are
- * being added in a correlated fashion, it will tend to push
- * the frequencies up for both of them. In this method we
- * compensate for cases like this by applying corrective
- * scaling.
- */
-
- static void adjust_freqs(void)
- {
- /*
- * Enforce minimum values for any frequencies that might potentially
- * be missing in the standard set, especially supercharged ones.
- * Numbers here represent the average number of times this ability
- * would appear if the entire randart set was eligible to receive
- * it (so in the case of a bow ability: if the set was all bows).
- *
- * Note that low numbers here for very specialized abilities could
- * mean that there's a good chance this ability will not appear in
- * a given randart set. If this is a problem, raise the number.
- */
- if (artprobs[ART_IDX_GEN_RFEAR] < 5)
- artprobs[ART_IDX_GEN_RFEAR] = 5;
- if (artprobs[ART_IDX_MELEE_DICE_SUPER] < 5)
- artprobs[ART_IDX_MELEE_DICE_SUPER] = 5;
- if (artprobs[ART_IDX_BOW_SHOTS_SUPER] < 5)
- artprobs[ART_IDX_BOW_SHOTS_SUPER] = 5;
- if (artprobs[ART_IDX_BOW_MIGHT_SUPER] < 5)
- artprobs[ART_IDX_BOW_MIGHT_SUPER] = 5;
- if (artprobs[ART_IDX_MELEE_BLOWS_SUPER] < 5)
- artprobs[ART_IDX_MELEE_BLOWS_SUPER] = 5;
- if (artprobs[ART_IDX_GEN_SPEED_SUPER] < 5)
- artprobs[ART_IDX_GEN_SPEED_SUPER] = 5;
- if (artprobs[ART_IDX_GEN_AC] < 5)
- artprobs[ART_IDX_GEN_AC] = 5;
- if (artprobs[ART_IDX_GEN_TUNN] < 5)
- artprobs[ART_IDX_GEN_TUNN] = 5;
- if (artprobs[ART_IDX_NONWEAPON_BRAND] < 2)
- artprobs[ART_IDX_NONWEAPON_BRAND] = 2;
- if (artprobs[ART_IDX_NONWEAPON_SLAY] < 2)
- artprobs[ART_IDX_NONWEAPON_SLAY] = 2;
- if (artprobs[ART_IDX_BOW_BRAND] < 2)
- artprobs[ART_IDX_BOW_BRAND] = 2;
- if (artprobs[ART_IDX_BOW_SLAY] < 2)
- artprobs[ART_IDX_BOW_SLAY] = 2;
- if (artprobs[ART_IDX_NONWEAPON_BLOWS] < 2)
- artprobs[ART_IDX_NONWEAPON_BLOWS] = 2;
- if (artprobs[ART_IDX_NONWEAPON_SHOTS] < 2)
- artprobs[ART_IDX_NONWEAPON_SHOTS] = 2;
- if (artprobs[ART_IDX_GEN_AC_SUPER] < 5)
- artprobs[ART_IDX_GEN_AC_SUPER] = 5;
- if (artprobs[ART_IDX_MELEE_AC] < 5)
- artprobs[ART_IDX_MELEE_AC] = 5;
-
- /* Cut aggravation frequencies in half since they're used twice */
- artprobs[ART_IDX_NONWEAPON_AGGR] /= 2;
- artprobs[ART_IDX_WEAPON_AGGR] /= 2;
- }
-
- /*
- * Parse the list of artifacts and count up the frequencies of the various
- * abilities. This is used to give dynamic generation probabilities.
- */
- static void parse_frequencies(void)
- {
- int i, j;
- const artifact_type *a_ptr;
- object_kind *k_ptr;
- s32b temp, temp2;
- s16b k_idx;
-
-
- LOG_PRINT("\n****** BEGINNING GENERATION OF FREQUENCIES\n\n");
-
- /* Zero the frequencies for artifact attributes */
- for (i = 0; i < ART_IDX_TOTAL; i++)
- {
- artprobs[i] = 0;
- }
-
- /*
- * Initialise the frequencies for base items so that each item could
- * be chosen - we check for illegal items during choose_item()
- */
- for (i = 0; i < z_info->k_max; i++)
- {
- baseprobs[i] = 1;
- }
-
- /* Go through the list of all artifacts */
- for (i = 0; i < z_info->a_max; i++)
- {
- LOG_PRINT1("Current artifact index is %d\n", i);
-
- a_ptr = &a_info[i];
-
- /* Special cases -- don't parse these! */
- if ((i == ART_POWER) ||
- (i == ART_GROND) ||
- (i == ART_MORGOTH))
- continue;
-
- /* Also don't parse cursed items */
- if (base_power[i] < 0) continue;
-
- /* Get a pointer to the base item for this artifact */
- k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
- k_ptr = &k_info[k_idx];
-
- /* Add the base item to the baseprobs array */
- baseprobs[k_idx]++;
- LOG_PRINT1("Base item is %d\n", k_idx);
-
- /* Count up the abilities for this artifact */
- if (a_ptr->tval == TV_BOW)
- {
- if(of_has(a_ptr->flags, OF_SHOTS))
- {
- /* Do we have 3 or more extra shots? (Unlikely) */
- if(a_ptr->pval > 2)
- {
- LOG_PRINT("Adding 1 for supercharged shots (3 or more!)\n");
-
- (artprobs[ART_IDX_BOW_SHOTS_SUPER])++;
- }
- else {
- LOG_PRINT("Adding 1 for extra shots\n");
-
- (artprobs[ART_IDX_BOW_SHOTS])++;
- }
- }
- if(of_has(a_ptr->flags, OF_MIGHT))
- {
- /* Do we have 3 or more extra might? (Unlikely) */
- if(a_ptr->pval > 2)
- {
- LOG_PRINT("Adding 1 for supercharged might (3 or more!)\n");
-
- (artprobs[ART_IDX_BOW_MIGHT_SUPER])++;
- }
- else {
- LOG_PRINT("Adding 1 for extra might\n");
-
- (artprobs[ART_IDX_BOW_MIGHT])++;
- }
- }
-
- /* Brands or slays - count all together */
- if (flags_test(a_ptr->flags, OF_SIZE, OF_ALL_SLAY_MASK, FLAG_END))
- {
- const slay_t *s_ptr;
-
- /* We have some brands or slays - count them */
- temp = 0;
- temp2 = 0;
-
- for (s_ptr = slay_table; s_ptr->slay_flag; s_ptr++)
- {
- if (of_has(a_ptr->flags, s_ptr->slay_flag))
- {
- bitflag slay_kill_mask[OF_SIZE], brand_mask[OF_SIZE];
-
- flags_init(brand_mask, OF_SIZE, OF_BRAND_MASK, FLAG_END);
- flags_init(slay_kill_mask, OF_SIZE, OF_SLAY_MASK, OF_KILL_MASK, FLAG_END);
-
- if (of_has(slay_kill_mask, s_ptr->slay_flag)) temp++;
- if (of_has(brand_mask, s_ptr->slay_flag)) temp2++;
- }
- }
- LOG_PRINT1("Adding %d for slays\n", temp);
- LOG_PRINT1("Adding %d for brands\n", temp2);
-
- /* Add these to the frequency count */
- artprobs[ART_IDX_BOW_SLAY] += temp;
- artprobs[ART_IDX_BOW_BRAND] += temp2;
- }
- }
-
- /* Handle hit / dam ratings - are they higher than normal? */
- /* Also handle other weapon/nonweapon abilities */
- if (a_ptr->tval == TV_BOW || a_ptr->tval == TV_DIGGING ||
- a_ptr->tval == TV_HAFTED || a_ptr->tval == TV_POLEARM ||
- a_ptr->tval == TV_SWORD)
- {
- if (a_ptr->to_h - randcalc(k_ptr->to_h, 0, MINIMISE) - mean_hit_startval > 0)
- {
- temp = (a_ptr->to_d - randcalc(k_ptr->to_d, 0, MINIMISE) - mean_dam_startval) /
- mean_dam_increment;
- if (temp > 0)
- {
- LOG_PRINT1("Adding %d instances of extra to-hit bonus for weapon\n", temp);
-
- (artprobs[ART_IDX_WEAPON_HIT]) += temp;
- }
- }
- else if (a_ptr->to_h - randcalc(k_ptr->to_h, 0, MINIMISE) - mean_hit_startval < 0)
- {
- temp = ( -(a_ptr->to_d - randcalc(k_ptr->to_d, 0, MINIMISE) - mean_dam_startval) ) /
- mean_dam_increment;
- if (temp > 0)
- {
- LOG_PRINT1("Subtracting %d instances of extra to-hit bonus for weapon\n", temp);
-
- (artprobs[ART_IDX_WEAPON_HIT]) -= temp;
- }
- }
- if (a_ptr->to_d - randcalc(k_ptr->to_d, 0, MINIMISE) - mean_dam_startval > 0)
- {
- temp = (a_ptr->to_d - randcalc(k_ptr->to_d, 0, MINIMISE) - mean_dam_startval) /
- mean_dam_increment;
- if (temp > 0)
- {
- LOG_PRINT1("Adding %d instances of extra to-dam bonus for weapon\n", temp);
-
- (artprobs[ART_IDX_WEAPON_DAM]) += temp;
- }
- }
- else if (a_ptr->to_d - randcalc(k_ptr->to_d, 0, MINIMISE) - mean_dam_startval < 0)
- {
- temp = ( -(a_ptr->to_d - randcalc(k_ptr->to_d, 0, MINIMISE) - mean_dam_startval)) /
- mean_dam_increment;
- if (temp > 0)
- {
- LOG_PRINT1("Subtracting %d instances of extra to-dam bonus for weapon\n", temp);
-
- (artprobs[ART_IDX_WEAPON_DAM]) -= temp;
- }
- }
-
- /* Aggravation */
- if (of_has(a_ptr->flags, OF_AGGRAVATE))
- {
- LOG_PRINT("Adding 1 for aggravation - weapon\n");
- (artprobs[ART_IDX_WEAPON_AGGR])++;
- }
-
- /* End weapon stuff */
- }
- else
- {
- if ( (a_ptr->to_h - randcalc(k_ptr->to_h, 0, MINIMISE) > 0) &&
- (a_ptr->to_h - randcalc(k_ptr->to_h, 0, MINIMISE) == a_ptr->to_d - randcalc(k_ptr->to_d, 0, MINIMISE)) )
- {
- /* Special case: both hit and dam bonuses present and equal */
- temp = (a_ptr->to_d - randcalc(k_ptr->to_d, 0, MINIMISE)) / mean_dam_increment;
- if (temp > 0)
- {
- LOG_PRINT1("Adding %d instances of extra to-hit and to-dam bonus for non-weapon\n", temp);
-
- (artprobs[ART_IDX_NONWEAPON_HIT_DAM]) += temp;
- }
- }
- else
- {
- /* Uneven bonuses - handle separately */
- if (a_ptr->to_h - randcalc(k_ptr->to_h, 0, MINIMISE) > 0)
- {
- temp = (a_ptr->to_d - randcalc(k_ptr->to_d, 0, MINIMISE)) / mean_dam_increment;
- if (temp > 0)
- {
- LOG_PRINT1("Adding %d instances of extra to-hit bonus for non-weapon\n", temp);
-
- (artprobs[ART_IDX_NONWEAPON_HIT]) += temp;
- }
- }
- if (a_ptr->to_d - randcalc(k_ptr->to_d, 0, MINIMISE) > 0)
- {
- temp = (a_ptr->to_d - randcalc(k_ptr->to_d, 0, MINIMISE)) / mean_dam_increment;
- if (temp > 0)
- {
- LOG_PRINT1("Adding %d instances of extra to-dam bonus for non-weapon\n", temp);
-
- (artprobs[ART_IDX_NONWEAPON_DAM]) += temp;
- }
- }
- }
-
- /* Aggravation */
- if (of_has(a_ptr->flags, OF_AGGRAVATE))
- {
- LOG_PRINT("Adding 1 for aggravation - nonweapon\n");
- (artprobs[ART_IDX_NONWEAPON_AGGR])++;
- }
-
- /* Brands or slays - count all together */
- if (flags_test(a_ptr->flags, OF_SIZE, OF_ALL_SLAY_MASK, FLAG_END))
- {
- const slay_t *s_ptr;
-
- /* We have some brands or slays - count them */
- temp = 0;
- temp2 = 0;
-
- for (s_ptr = slay_table; s_ptr->slay_flag; s_ptr++)
- {
- if (of_has(a_ptr->flags, s_ptr->slay_flag))
- {
- bitflag slay_kill_mask[OF_SIZE], brand_mask[OF_SIZE];
-
- flags_init(brand_mask, OF_SIZE, OF_BRAND_MASK, FLAG_END);
- flags_init(slay_kill_mask, OF_SIZE, OF_SLAY_MASK, FLAG_END);
- flags_set(slay_kill_mask, OF_SIZE, OF_KILL_MASK, FLAG_END);
-
- if (of_has(slay_kill_mask, s_ptr->slay_flag)) temp++;
- if (of_has(brand_mask, s_ptr->slay_flag)) temp2++;
- }
- }
- LOG_PRINT1("Adding %d for slays\n", temp);
- LOG_PRINT1("Adding %d for brands\n", temp2);
-
- /* Add these to the frequency count */
- artprobs[ART_IDX_NONWEAPON_SLAY] += temp;
- artprobs[ART_IDX_NONWEAPON_BRAND] += temp2;
- }
-
- if (of_has(a_ptr->flags, OF_BLOWS))
- {
- LOG_PRINT("Adding 1 for extra blows on nonweapon\n");
- (artprobs[ART_IDX_NONWEAPON_BLOWS])++;
- }
-
- if (of_has(a_ptr->flags, OF_SHOTS))
- {
- LOG_PRINT("Adding 1 for extra shots on nonweapon\n");
- (artprobs[ART_IDX_NONWEAPON_SHOTS])++;
- }
- }
-
- if (a_ptr->tval == TV_DIGGING || a_ptr->tval == TV_HAFTED ||
- a_ptr->tval == TV_POLEARM || a_ptr->tval == TV_SWORD)
- {
- /* Blessed weapon? */
- if (of_has(a_ptr->flags, OF_BLESSED))
- {
- LOG_PRINT("Adding 1 for blessed weapon\n");
-
- (artprobs[ART_IDX_MELEE_BLESS])++;
- }
-
- /* See invisible? */
- if (of_has(a_ptr->flags, OF_SEE_INVIS))
- {
- LOG_PRINT("Adding 1 for see invisible (weapon case)\n");
-
- (artprobs[ART_IDX_MELEE_SINV])++;
- }
-
- /* Does this weapon have extra blows? */
- if (of_has(a_ptr->flags, OF_BLOWS))
- {
- /* Do we have 3 or more extra blows? (Unlikely) */
- if(a_ptr->pval > 2)
- {
- LOG_PRINT("Adding 1 for supercharged blows (3 or more!)\n");
- (artprobs[ART_IDX_MELEE_BLOWS_SUPER])++;
- }
- else {
- LOG_PRINT("Adding 1 for extra blows\n");
- (artprobs[ART_IDX_MELEE_BLOWS])++;
- }
- }
-
- /* Does this weapon have an unusual bonus to AC? */
- if ( (a_ptr->to_a - randcalc(k_ptr->to_a, 0, MAXIMISE)) > 0)
- {
- temp = (a_ptr->to_a - randcalc(k_ptr->to_a, 0, MAXIMISE)) / mean_ac_increment;
- if (temp > 0)
- {
- LOG_PRINT1("Adding %d instances of extra AC bonus for weapon\n", temp);
-
- (artprobs[ART_IDX_MELEE_AC]) += temp;
- }
- }
-
- /* Check damage dice - are they more than normal? */
- if (a_ptr->dd > k_ptr->dd)
- {
- /* Difference of 3 or more? */
- if ( (a_ptr->dd - k_ptr->dd) > 2)
- {
- LOG_PRINT("Adding 1 for super-charged damage dice!\n");
-
- (artprobs[ART_IDX_MELEE_DICE_SUPER])++;
- }
- else
- {
- LOG_PRINT("Adding 1 for extra damage dice.\n");
-
- (artprobs[ART_IDX_MELEE_DICE])++;
- }
- }
-
- /* Check weight - is it different from normal? */
- if (a_ptr->weight != k_ptr->weight)
- {
- LOG_PRINT("Adding 1 for unusual weight.\n");
-
- (artprobs[ART_IDX_MELEE_WEIGHT])++;
- }
-
- /* Check for tunnelling ability */
- if (of_has(a_ptr->flags, OF_TUNNEL))
- {
- LOG_PRINT("Adding 1 for tunnelling bonus.\n");
-
- (artprobs[ART_IDX_MELEE_TUNN])++;
- }
-
- /* Brands or slays - count all together */
- if (flags_test(a_ptr->flags, OF_SIZE, OF_ALL_SLAY_MASK, FLAG_END))
- {
- const slay_t *s_ptr;
-
- /* We have some brands or slays - count them */
- temp = 0;
- temp2 = 0;
-
- for (s_ptr = slay_table; s_ptr->slay_flag; s_ptr++)
- {
- if (of_has(a_ptr->flags, s_ptr->slay_flag))
- {
- bitflag slay_kill_mask[OF_SIZE], brand_mask[OF_SIZE];
-
- flags_init(brand_mask, OF_SIZE, OF_BRAND_MASK, FLAG_END);
- flags_init(slay_kill_mask, OF_SIZE, OF_SLAY_MASK, FLAG_END);
- flags_set(slay_kill_mask, OF_SIZE, OF_KILL_MASK, FLAG_END);
-
- if (of_has(slay_kill_mask, s_ptr->slay_flag)) temp++;
- if (of_has(brand_mask, s_ptr->slay_flag)) temp2++;
- }
- }
- LOG_PRINT1("Adding %d for slays\n", temp);
- LOG_PRINT1("Adding %d for brands\n", temp2);
-
- /* Add these to the frequency count */
- artprobs[ART_IDX_MELEE_SLAY] += temp;
- artprobs[ART_IDX_MELEE_BRAND] += temp2;
- }
-
- /* End of weapon-specific stuff */
- }
- else
- {
- /* Check for tunnelling ability */
- if (of_has(a_ptr->flags, OF_TUNNEL))
- {
- LOG_PRINT("Adding 1 for tunnelling bonus - general.\n");
-
- (artprobs[ART_IDX_GEN_TUNN])++;
- }
- }
-
- /*
- * Count up extra AC bonus values.
- * Could also add logic to subtract for lower values here, but it's
- * probably not worth the trouble since it's so rare.
- */
-
- if ( (a_ptr->to_a - randcalc(k_ptr->to_a, 0, MINIMISE) - mean_ac_startval) > 0)
- {
- temp = (a_ptr->to_a - randcalc(k_ptr->to_a, 0, MINIMISE) - mean_ac_startval) /
- mean_ac_increment;
- if (temp > 0)
- {
- if (a_ptr->to_a > 20)
- {
- LOG_PRINT1("Adding %d for supercharged AC\n", temp);
- (artprobs[ART_IDX_GEN_AC_SUPER])++;
- }
- else if (a_ptr->tval == TV_BOOTS)
- {
- LOG_PRINT1("Adding %d for AC bonus - boots\n", temp);
- (artprobs[ART_IDX_BOOT_AC]) += temp;
- }
- else if (a_ptr->tval == TV_GLOVES)
- {
- LOG_PRINT1("Adding %d for AC bonus - gloves\n", temp);
- (artprobs[ART_IDX_GLOVE_AC]) += temp;
- }
- else if (a_ptr->tval == TV_HELM || a_ptr->tval == TV_CROWN)
- {
- LOG_PRINT1("Adding %d for AC bonus - headgear\n", temp);
- (artprobs[ART_IDX_HELM_AC]) += temp;
- }
- else if (a_ptr->tval == TV_SHIELD)
- {
- LOG_PRINT1("Adding %d for AC bonus - shield\n", temp);
- (artprobs[ART_IDX_SHIELD_AC]) += temp;
- }
- else if (a_ptr->tval == TV_CLOAK)
- {
- LOG_PRINT1("Adding %d for AC bonus - cloak\n", temp);
- (artprobs[ART_IDX_CLOAK_AC]) += temp;
- }
- else if (a_ptr->tval == TV_SOFT_ARMOR || a_ptr->tval == TV_HARD_ARMOR ||
- a_ptr->tval == TV_DRAG_ARMOR)
- {
- LOG_PRINT1("Adding %d for AC bonus - body armor\n", temp);
- (artprobs[ART_IDX_ARMOR_AC]) += temp;
- }
- else
- {
- LOG_PRINT1("Adding %d for AC bonus - general\n", temp);
- (artprobs[ART_IDX_GEN_AC]) += temp;
- }
- }
- }
-
- /* Generic armor abilities */
- if (a_ptr->tval == TV_BOOTS || a_ptr->tval == TV_GLOVES ||
- a_ptr->tval == TV_HELM || a_ptr->tval == TV_CROWN ||
- a_ptr->tval == TV_SHIELD || a_ptr->tval == TV_CLOAK ||
- a_ptr->tval == TV_SOFT_ARMOR || a_ptr->tval == TV_HARD_ARMOR ||
- a_ptr->tval == TV_DRAG_ARMOR)
- {
- /* Check weight - is it different from normal? */
- /* ToDo: count higher and lower separately */
- if (a_ptr->weight != k_ptr->weight)
- {
- LOG_PRINT("Adding 1 for unusual weight.\n");
-
- (artprobs[ART_IDX_ALLARMOR_WEIGHT])++;
- }
-
- /* Done with generic armor abilities */
- }
-
- /*
- * General abilities. This section requires a bit more work
- * than the others, because we have to consider cases where
- * a certain ability might be found in a particular item type.
- * For example, ESP is commonly found on headgear, so when
- * we count ESP we must add it to either the headgear or
- * general tally, depending on the base item. This permits
- * us to have general abilities appear more commonly on a
- * certain item type.
- */
-
- if (flags_test(a_ptr->flags, OF_SIZE, OF_STR, OF_INT, OF_WIS,
- OF_DEX, OF_CON, OF_CHR, FLAG_END))
- {
- /* Stat bonus case. Add up the number of individual
- bonuses */
- temp = 0;
- if (of_has(a_ptr->flags, OF_STR)) temp++;
- if (of_has(a_ptr->flags, OF_INT)) temp++;
- if (of_has(a_ptr->flags, OF_WIS)) temp++;
- if (of_has(a_ptr->flags, OF_DEX)) temp++;
- if (of_has(a_ptr->flags, OF_CON)) temp++;
- if (of_has(a_ptr->flags, OF_CHR)) temp++;
-
- /* Handle a few special cases separately. */
- if((a_ptr->tval == TV_HELM || a_ptr->tval == TV_CROWN) &&
- (of_has(a_ptr->flags, OF_WIS) || of_has(a_ptr->flags, OF_INT)))
- {
- /* Handle WIS and INT on helms and crowns */
- if(of_has(a_ptr->flags, OF_WIS))
- {
- LOG_PRINT("Adding 1 for WIS bonus on headgear.\n");
-
- (artprobs[ART_IDX_HELM_WIS])++;
- /* Counted this one separately so subtract it here */
- temp--;
- }
- if(of_has(a_ptr->flags, OF_INT))
- {
- LOG_PRINT("Adding 1 for INT bonus on headgear.\n");
-
- (artprobs[ART_IDX_HELM_INT])++;
- /* Counted this one separately so subtract it here */
- temp--;
- }
- }
- else if ((a_ptr->tval == TV_SOFT_ARMOR ||
- a_ptr->tval == TV_HARD_ARMOR ||
- a_ptr->tval == TV_DRAG_ARMOR) && of_has(a_ptr->flags, OF_CON))
- {
- /* Handle CON bonus on armor */
- LOG_PRINT("Adding 1 for CON bonus on body armor.\n");
-
- (artprobs[ART_IDX_ARMOR_CON])++;
- /* Counted this one separately so subtract it here */
- temp--;
- }
- else if (a_ptr->tval == TV_GLOVES && of_has(a_ptr->flags, OF_DEX))
- {
- /* Handle DEX bonus on gloves */
- LOG_PRINT("Adding 1 for DEX bonus on gloves.\n");
-
- (artprobs[ART_IDX_GLOVE_DEX])++;
- /* Counted this one separately so subtract it here */
- temp--;
- }
-
- /* Now the general case */
- if (temp > 0)
- {
- /* There are some bonuses that weren't handled above */
- LOG_PRINT1("Adding %d for stat bonuses - general.\n", temp);
-
- (artprobs[ART_IDX_GEN_STAT]) += temp;
-
- /* Done with stat bonuses */
- }
- }
-
- if (flags_test(a_ptr->flags, OF_SIZE, OF_SUST_STR, OF_SUST_INT,
- OF_SUST_WIS, OF_SUST_DEX, OF_SUST_CON,
- OF_SUST_CHR, FLAG_END))
- {
- /* Now do sustains, in a similar manner */
- temp = 0;
- if (of_has(a_ptr->flags, OF_SUST_STR)) temp++;
- if (of_has(a_ptr->flags, OF_SUST_INT)) temp++;
- if (of_has(a_ptr->flags, OF_SUST_WIS)) temp++;
- if (of_has(a_ptr->flags, OF_SUST_DEX)) temp++;
- if (of_has(a_ptr->flags, OF_SUST_CON)) temp++;
- if (of_has(a_ptr->flags, OF_SUST_CHR)) temp++;
- LOG_PRINT1("Adding %d for stat sustains.\n", temp);
-
- (artprobs[ART_IDX_GEN_SUST]) += temp;
- }
-
- if (of_has(a_ptr->flags, OF_STEALTH))
- {
- /* Handle stealth, including a couple of special cases */
- if(a_ptr->tval == TV_BOOTS)
- {
- LOG_PRINT("Adding 1 for stealth bonus on boots.\n");
-
- (artprobs[ART_IDX_BOOT_STEALTH])++;
- }
- else if (a_ptr->tval == TV_CLOAK)
- {
- LOG_PRINT("Adding 1 for stealth bonus on cloak.\n");
-
- (artprobs[ART_IDX_CLOAK_STEALTH])++;
- }
- else if (a_ptr->tval == TV_SOFT_ARMOR ||
- a_ptr->tval == TV_HARD_ARMOR || a_ptr->tval == TV_DRAG_ARMOR)
- {
- LOG_PRINT("Adding 1 for stealth bonus on armor.\n");
-
- (artprobs[ART_IDX_ARMOR_STEALTH])++;
- }
- else
- {
- /* General case */
- LOG_PRINT("Adding 1 for stealth bonus - general.\n");
-
- (artprobs[ART_IDX_GEN_STEALTH])++;
- }
- /* Done with stealth */
- }
-
- if (of_has(a_ptr->flags, OF_SEARCH))
- {
- /* Handle searching bonus - fully generic this time */
- LOG_PRINT("Adding 1 for search bonus - general.\n");
-
- (artprobs[ART_IDX_GEN_SEARCH])++;
- }
-
- if (of_has(a_ptr->flags, OF_INFRA))
- {
- /* Handle infravision bonus - fully generic */
- LOG_PRINT("Adding 1 for infravision bonus - general.\n");
-
- (artprobs[ART_IDX_GEN_INFRA])++;
- }
-
- if (of_has(a_ptr->flags, OF_SPEED))
- {
- /*
- * Speed - boots handled separately.
- * This is something of a special case in that we use the same
- * frequency for the supercharged value and the normal value.
- * We get away with this by using a somewhat lower average value
- * for the supercharged ability than in the basic set (around
- * +7 or +8 - c.f. Ringil and the others at +10 and upwards).
- * This then allows us to add an equal number of
- * small bonuses around +3 or so without unbalancing things.
- */
-
- if (a_ptr->pval > 7)
- {
- /* Supercharge case */
- LOG_PRINT("Adding 1 for supercharged speed bonus!\n");
-
- (artprobs[ART_IDX_GEN_SPEED_SUPER])++;
- }
- else if(a_ptr->tval == TV_BOOTS)
- {
- /* Handle boots separately */
- LOG_PRINT("Adding 1 for normal speed bonus on boots.\n");
-
- (artprobs[ART_IDX_BOOT_SPEED])++;
- }
- else
- {
- LOG_PRINT("Adding 1 for normal speed bonus - general.\n");
-
- (artprobs[ART_IDX_GEN_SPEED])++;
- }
- /* Done with speed */
- }
-
- if (flags_test(a_ptr->flags, OF_SIZE, OF_IM_ACID, OF_IM_ELEC,
- OF_IM_FIRE, OF_IM_COLD, FLAG_END))
- {
- /* Count up immunities for this item, if any */
- temp = 0;
- if (of_has(a_ptr->flags, OF_IM_ACID)) temp++;
- if (of_has(a_ptr->flags, OF_IM_ELEC)) temp++;
- if (of_has(a_ptr->flags, OF_IM_FIRE)) temp++;
- if (of_has(a_ptr->flags, OF_IM_COLD)) temp++;
- LOG_PRINT1("Adding %d for immunities.\n", temp);
-
- (artprobs[ART_IDX_GEN_IMMUNE]) += temp;
- }
-
- if (of_has(a_ptr->flags, OF_FREE_ACT))
- {
- /* Free action - handle gloves separately */
- if(a_ptr->tval == TV_GLOVES)
- {
- LOG_PRINT("Adding 1 for free action on gloves.\n");
-
- (artprobs[ART_IDX_GLOVE_FA])++;
- }
- else
- {
- LOG_PRINT("Adding 1 for free action - general.\n");
-
- (artprobs[ART_IDX_GEN_FA])++;
- }
- }
-
- if (of_has(a_ptr->flags, OF_HOLD_LIFE))
- {
- /* Hold life - do body armor separately */
- if( (a_ptr->tval == TV_SOFT_ARMOR) || (a_ptr->tval == TV_HARD_ARMOR) ||
- (a_ptr->tval == TV_DRAG_ARMOR))
- {
- LOG_PRINT("Adding 1 for hold life on armor.\n");
-
- (artprobs[ART_IDX_ARMOR_HLIFE])++;
- }
- else
- {
- LOG_PRINT("Adding 1 for hold life - general.\n");
-
- (artprobs[ART_IDX_GEN_HLIFE])++;
- }
- }
-
- if (of_has(a_ptr->flags, OF_FEATHER))
- {
- /* Feather fall - handle boots separately */
- if(a_ptr->tval == TV_BOOTS)
- {
- LOG_PRINT("Adding 1 for feather fall on boots.\n");
-
- (artprobs[ART_IDX_BOOT_FEATHER])++;
- }
- else
- {
- LOG_PRINT("Adding 1 for feather fall - general.\n");
-
- (artprobs[ART_IDX_GEN_FEATHER])++;
- }
- }
-
- if (of_has(a_ptr->flags, OF_LIGHT))
- {
- /* Handle permanent light */
- LOG_PRINT("Adding 1 for permanent light - general.\n");
-
- (artprobs[ART_IDX_GEN_LIGHT])++;
- }
-
- if (of_has(a_ptr->flags, OF_SEE_INVIS))
- {
- /*
- * Handle see invisible - do helms / crowns separately
- * (Weapons were done already so exclude them)
- */
- if( !(a_ptr->tval == TV_DIGGING || a_ptr->tval == TV_HAFTED ||
- a_ptr->tval == TV_POLEARM || a_ptr->tval == TV_SWORD))
- {
- if (a_ptr->tval == TV_HELM || a_ptr->tval == TV_CROWN)
- {
- LOG_PRINT("Adding 1 for see invisible - headgear.\n");
-
- (artprobs[ART_IDX_HELM_SINV])++;
- }
- else
- {
- LOG_PRINT("Adding 1 for see invisible - general.\n");
-
- (artprobs[ART_IDX_GEN_SINV])++;
- }
- }
- }
-
- if (of_has(a_ptr->flags, OF_TELEPATHY))
- {
- /* ESP case. Handle helms/crowns separately. */
- if(a_ptr->tval == TV_HELM || a_ptr->tval == TV_CROWN)
- {
- LOG_PRINT("Adding 1 for ESP on headgear.\n");
-
- (artprobs[ART_IDX_HELM_ESP])++;
- }
- else
- {
- LOG_PRINT("Adding 1 for ESP - general.\n");
-
- (artprobs[ART_IDX_GEN_ESP])++;
- }
- }
-
- if (of_has(a_ptr->flags, OF_SLOW_DIGEST))
- {
- /* Slow digestion case - generic. */
- LOG_PRINT("Adding 1 for slow digestion - general.\n");
-
- (artprobs[ART_IDX_GEN_SDIG])++;
- }
-
- if (of_has(a_ptr->flags, OF_REGEN))
- {
- /* Regeneration case - generic. */
- LOG_PRINT("Adding 1 for regeneration - general.\n");
-
- (artprobs[ART_IDX_GEN_REGEN])++;
- }
-
- if (flags_test(a_ptr->flags, OF_SIZE, OF_RES_ACID, OF_RES_ELEC,
- OF_RES_FIRE, OF_RES_COLD, FLAG_END))
- {
- /* Count up low resists (not the type, just the number) */
- temp = 0;
- if (of_has(a_ptr->flags, OF_RES_ACID)) temp++;
- if (of_has(a_ptr->flags, OF_RES_ELEC)) temp++;
- if (of_has(a_ptr->flags, OF_RES_FIRE)) temp++;
- if (of_has(a_ptr->flags, OF_RES_COLD)) temp++;
-
- /* Shields treated separately */
- if (a_ptr->tval == TV_SHIELD)
- {
- LOG_PRINT1("Adding %d for low resists on shield.\n", temp);
-
- (artprobs[ART_IDX_SHIELD_LRES]) += temp;
- }
- else if (a_ptr->tval == TV_SOFT_ARMOR ||
- a_ptr->tval == TV_HARD_ARMOR || a_ptr->tval == TV_DRAG_ARMOR)
- {
- /* Armor also treated separately */
- if (temp == 4)
- {
- /* Special case: armor has all four low resists */
- LOG_PRINT("Adding 1 for ALL LOW RESISTS on body armor.\n");
-
- (artprobs[ART_IDX_ARMOR_ALLRES])++;
- }
- else
- {
- /* Just tally up the resists as usual */
- LOG_PRINT1("Adding %d for low resists on body armor.\n", temp);
-
- (artprobs[ART_IDX_ARMOR_LRES]) += temp;
- }
- }
- else
- {
- /* General case */
- LOG_PRINT1("Adding %d for low resists - general.\n", temp);
-
- (artprobs[ART_IDX_GEN_LRES]) += temp;
- }
-
- /* Done with low resists */
- }
-
- /*
- * If the item is body armor then count up all the high resists before
- * going through them individually. High resists are an important
- * component of body armor so we track probability for them separately.
- * The proportions of the high resists will be determined by the
- * generic frequencies - this number just tracks the total.
- */
- if (a_ptr->tval == TV_SOFT_ARMOR ||
- a_ptr->tval == TV_HARD_ARMOR || a_ptr->tval == TV_DRAG_ARMOR)
- {
- temp = 0;
- if (of_has(a_ptr->flags, OF_RES_POIS)) temp++;
- if (of_has(a_ptr->flags, OF_RES_FEAR)) temp++;
- if (of_has(a_ptr->flags, OF_RES_LIGHT)) temp++;
- if (of_has(a_ptr->flags, OF_RES_DARK)) temp++;
- if (of_has(a_ptr->flags, OF_RES_BLIND)) temp++;
- if (of_has(a_ptr->flags, OF_RES_CONFU)) temp++;
- if (of_has(a_ptr->flags, OF_RES_SOUND)) temp++;
- if (of_has(a_ptr->flags, OF_RES_SHARD)) temp++;
- if (of_has(a_ptr->flags, OF_RES_NEXUS)) temp++;
- if (of_has(a_ptr->flags, OF_RES_NETHR)) temp++;
- if (of_has(a_ptr->flags, OF_RES_CHAOS)) temp++;
- if (of_has(a_ptr->flags, OF_RES_DISEN)) temp++;
- LOG_PRINT1("Adding %d for high resists on body armor.\n", temp);
-
- (artprobs[ART_IDX_ARMOR_HRES]) += temp;
- }
-
- /* Now do the high resists individually */
- if (of_has(a_ptr->flags, OF_RES_POIS))
- {
- /* Resist poison ability */
- LOG_PRINT("Adding 1 for resist poison - general.\n");
-
- (artprobs[ART_IDX_GEN_RPOIS])++;
- }
-
- if (of_has(a_ptr->flags, OF_RES_FEAR))
- {
- /* Resist fear ability */
- LOG_PRINT("Adding 1 for resist fear - general.\n");
-
- (artprobs[ART_IDX_GEN_RFEAR])++;
- }
-
- if (of_has(a_ptr->flags, OF_RES_LIGHT))
- {
- /* Resist light ability */
- LOG_PRINT("Adding 1 for resist light - general.\n");
-
- (artprobs[ART_IDX_GEN_RLIGHT])++;
- }
-
- if (of_has(a_ptr->flags, OF_RES_DARK))
- {
- /* Resist dark ability */
- LOG_PRINT("Adding 1 for resist dark - general.\n");
-
- (artprobs[ART_IDX_GEN_RDARK])++;
- }
-
- if (of_has(a_ptr->flags, OF_RES_BLIND))
- {
- /* Resist blind ability - helms/crowns are separate */
- if(a_ptr->tval == TV_HELM || a_ptr->tval == TV_CROWN)
- {
- LOG_PRINT("Adding 1 for resist blindness - headgear.\n");
-
- (artprobs[ART_IDX_HELM_RBLIND])++;
- }
- else
- {
- /* General case */
- LOG_PRINT("Adding 1 for resist blindness - general.\n");
-
- (artprobs[ART_IDX_GEN_RBLIND])++;
- }
- }
-
- if (of_has(a_ptr->flags, OF_RES_CONFU))
- {
- /* Resist confusion ability */
- LOG_PRINT("Adding 1 for resist confusion - general.\n");
-
- (artprobs[ART_IDX_GEN_RCONF])++;
- }
-
- if (of_has(a_ptr->flags, OF_RES_SOUND))
- {
- /* Resist sound ability */
- LOG_PRINT("Adding 1 for resist sound - general.\n");
-
- (artprobs[ART_IDX_GEN_RSOUND])++;
- }
-
- if (of_has(a_ptr->flags, OF_RES_SHARD))
- {
- /* Resist shards ability */
- LOG_PRINT("Adding 1 for resist shards - general.\n");
-
- (artprobs[ART_IDX_GEN_RSHARD])++;
- }
-
- if (of_has(a_ptr->flags, OF_RES_NEXUS))
- {
- /* Resist nexus ability */
- LOG_PRINT("Adding 1 for resist nexus - general.\n");
-
- (artprobs[ART_IDX_GEN_RNEXUS])++;
- }
-
- if (of_has(a_ptr->flags, OF_RES_NETHR))
- {
- /* Resist nether ability */
- LOG_PRINT("Adding 1 for resist nether - general.\n");
-
- (artprobs[ART_IDX_GEN_RNETHER])++;
- }
-
- if (of_has(a_ptr->flags, OF_RES_CHAOS))
- {
- /* Resist chaos ability */
- LOG_PRINT("Adding 1 for resist chaos - general.\n");
-
- (artprobs[ART_IDX_GEN_RCHAOS])++;
- }
-
- if (of_has(a_ptr->flags, OF_RES_DISEN))
- {
- /* Resist disenchantment ability */
- LOG_PRINT("Adding 1 for resist disenchantment - general.\n");
-
- (artprobs[ART_IDX_GEN_RDISEN])++;
- }
-
- if (a_ptr->effect)
- {
- /* Activation */
- LOG_PRINT("Adding 1 for activation.\n");
- (artprobs[ART_IDX_GEN_ACTIV])++;
- }
- /* Done with parsing of frequencies for this item */
- }
- /* End for loop */
-
- if (verbose)
- {
- /* Print out some of the abilities, to make sure that everything's fine */
- for (i = 0; i < ART_IDX_TOTAL; i++)
- {
- file_putf(log_file, "Frequency of ability %d: %d\n", i, artprobs[i]);
- }
-
- …
Large files files are truncated, but you can click here to view the full file