/** * Calculate the rating for a given slay combination */ static s32b slay_power(const object_type *obj, int p, int verbose, int dice_pwr, bool known) { u32b sv = 0; int i, q, num_brands = 0, num_slays = 0, num_kills = 0; int mult; int tot_mon_power = 0; struct brand *brands = obj->brands; struct slay *slays = obj->slays; /* Count the known brands and slays */ while (brands) { if (known || brands->known) num_brands++; brands = brands->next; } while (slays) { if (known || slays->known) { if (slays->multiplier <= 3) num_slays++; else num_kills++; } slays = slays->next; } /* If there are no slays or brands return */ if ((num_slays + num_brands + num_kills) == 0) return p; /* Look in the cache to see if we know this one yet */ sv = check_slay_cache(obj); /* If it's cached (or there are no slays), return the value */ if (sv) { log_obj("Slay cache hit\n"); } else { /* * Otherwise we need to calculate the expected average multiplier * for this combination (multiplied by the total number of * monsters, which we'll divide out later). */ for (i = 0; i < z_info->r_max; i++) { monster_type *mon = mem_zalloc(sizeof(*mon)); const struct brand *b = NULL; const struct slay *s = NULL; char verb[20]; mult = 1; mon->race = &r_info[i]; /* Find the best multiplier against this monster */ improve_attack_modifier((object_type *)obj, mon, &b, &s, verb, FALSE, FALSE, !known); if (s) mult = s->multiplier; else if (b) mult = b->multiplier; /* Add up totals */ tot_mon_power += mon->race->scaled_power; sv += mult * mon->race->scaled_power; mem_free(mon); } /* * To get the expected damage for this weapon, multiply the * average damage from base dice by sv, and divide by the * total number of monsters. */ if (verbose) { struct brand *b, *brands = NULL; struct slay *s, *slays = NULL; /* Write info about the slay combination and multiplier */ log_obj("Slay multiplier for: "); brands = brand_collect(obj->brands, NULL, !known); slays = slay_collect(obj->slays, NULL, !known); for (b = brands; b; b = b->next) { log_obj(format("%sx%d ", b->name, b->multiplier)); } for (s = slays; s; s = s->next) { log_obj(format("%sx%d ", s->name, s->multiplier)); } log_obj(format("\nsv is: %d\n", sv)); log_obj(format(" and t_m_p is: %d \n", tot_mon_power)); log_obj(format("times 1000 is: %d\n", (1000 * sv) / tot_mon_power)); free_brand(brands); free_slay(slays); } /* Add to the cache */ if (fill_slay_cache(obj, sv)) log_obj("Added to slay cache\n"); } q = (dice_pwr * (sv / 100)) / (tot_mon_power / 100); p += q; log_obj(format("Add %d for slay power, total is %d\n", q, p)); /* Bonuses for multiple brands and slays */ if (num_slays > 1) { q = (num_slays * num_slays * dice_pwr) / (DAMAGE_POWER * 5); p += q; log_obj(format("Add %d power for multiple slays, total is %d\n", q, p)); } if (num_brands > 1) { q = (2 * num_brands * num_brands * dice_pwr) / (DAMAGE_POWER * 5); p += q; log_obj(format("Add %d power for multiple brands, total is %d\n",q, p)); } if (num_kills > 1) { q = (3 * num_kills * num_kills * dice_pwr) / (DAMAGE_POWER * 5); p += q; log_obj(format("Add %d power for multiple kills, total is %d\n", q, p)); } if (num_slays == 8) { p += 10; log_obj(format("Add 10 power for full set of slays, total is %d\n", p)); } if (num_brands == 5) { p += 20; log_obj(format("Add 20 power for full set of brands, total is %d\n",p)); } if (num_kills == 3) { p += 20; log_obj(format("Add 20 power for full set of kills, total is %d\n", p)); } return p; }
/** * Calculate the rating for a given slay combination */ static s32b slay_power(const object_type *o_ptr, int verbose, ang_file* log_file, bool known) { bitflag s_index[OF_SIZE], f[OF_SIZE], f2[OF_SIZE]; u32b sv = 0; int i, j; int mult; const struct slay *best_s_ptr = NULL; monster_race *r_ptr; monster_type *m_ptr; monster_type monster_type_body; const char *desc[SL_MAX] = { 0 }, *brand[SL_MAX] = { 0 }; int s_mult[SL_MAX] = { 0 }; if (known) object_flags(o_ptr, f); else object_flags_known(o_ptr, f); /* Combine the slay bytes into an index value, return if there are none */ of_copy(s_index, f); create_mask(f2, FALSE, OFT_SLAY, OFT_KILL, OFT_BRAND, OFT_MAX); if (!of_is_inter(s_index, f2)) return tot_mon_power; else of_inter(s_index, f2); /* Look in the cache to see if we know this one yet */ sv = check_slay_cache(s_index); /* If it's cached (or there are no slays), return the value */ if (sv) { file_putf(log_file, "Slay cache hit\n"); return sv; } /* * Otherwise we need to calculate the expected average multiplier * for this combination (multiplied by the total number of * monsters, which we'll divide out later). */ for (i = 0; i < z_info->r_max; i++) { best_s_ptr = NULL; mult = 1; r_ptr = &r_info[i]; m_ptr = &monster_type_body; m_ptr->r_idx = i; /* Find the best multiplier against this monster */ improve_attack_modifier((object_type *)o_ptr, m_ptr, &best_s_ptr, FALSE, !known); if (best_s_ptr) mult = best_s_ptr->mult; /* Add the multiple to sv */ sv += mult * r_ptr->scaled_power; } /* * To get the expected damage for this weapon, multiply the * average damage from base dice by sv, and divide by the * total number of monsters. */ if (verbose) { /* Write info about the slay combination and multiplier */ file_putf(log_file, "Slay multiplier for: "); j = list_slays(s_index, s_index, desc, brand, s_mult, FALSE); for (i = 0; i < j; i++) { if (brand[i]) { file_putf(log_file, brand[i]); } else { file_putf(log_file, desc[i]); } file_putf(log_file, "x%d ", s_mult[i]); } file_putf(log_file, "\nsv is: %d\n", sv); file_putf(log_file, " and t_m_p is: %d \n", tot_mon_power); file_putf(log_file, "times 1000 is: %d\n", (1000 * sv) / tot_mon_power); } /* Add to the cache */ if (fill_slay_cache(s_index, sv)) file_putf(log_file, "Added to slay cache\n"); return sv; }