Skip to content

Commit

Permalink
Fix hit chance calculation and armor rating display
Browse files Browse the repository at this point in the history
Fixes the hit chance calculation for armor ratings ending in 0.25 and 0.75, and avoids rounding armor ratings to integers in the UI. It displays 1 decimal place, so 3.75 is displayed as 3.7, but this is probably fine since it doesn't make much difference.

Fixes #596
  • Loading branch information
nstoddard committed Aug 31, 2023
1 parent 4c0f0a5 commit 377e222
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 21 deletions.
2 changes: 2 additions & 0 deletions changes/armor-rating-rounding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix armor ratings like "3.5" being rounded to integers in the UI.
Fix armor ratings that end in 0.25 and 0.75 being equivalent to that armor rating minus 0.25.
8 changes: 4 additions & 4 deletions src/brogue/IO.c
Original file line number Diff line number Diff line change
Expand Up @@ -4522,8 +4522,8 @@ void highlightScreenCell(short x, short y, color *highlightColor, short strength

// Like `armorValueIfUnenchanted` for the currently-equipped armor, but takes the penalty from
// donning into account.
static short estimatedArmorValue() {
short retVal = armorValueIfUnenchanted(rogue.armor) - player.status[STATUS_DONNING];
static float estimatedArmorValue() {
float retVal = armorValueIfUnenchanted(rogue.armor) - player.status[STATUS_DONNING];
return max(0, retVal);
}

Expand Down Expand Up @@ -4799,13 +4799,13 @@ short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight)

if (!rogue.armor || rogue.armor->flags & ITEM_IDENTIFIED || rogue.playbackOmniscience) {

sprintf(buf, "Str: %s%i%s Armor: %i",
sprintf(buf, "Str: %s%i%s Armor: %g",
tempColorEscape,
rogue.strength - player.weaknessAmount,
grayColorEscape,
displayedArmorValue());
} else {
sprintf(buf, "Str: %s%i%s Armor: %i?",
sprintf(buf, "Str: %s%i%s Armor: %g?",
tempColorEscape,
rogue.strength - player.weaknessAmount,
grayColorEscape,
Expand Down
28 changes: 14 additions & 14 deletions src/brogue/Items.c
Original file line number Diff line number Diff line change
Expand Up @@ -2047,23 +2047,23 @@ void itemDetails(char *buf, item *theItem) {
abs((short) damageChange),
whiteColorEscape);
} else {
new = 0;
float armorValue;

if ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) {
new = theItem->armor;
new += 10 * netEnchant(theItem) / FP_FACTOR;
new /= 10;
armorValue = theItem->armor;
armorValue += 10 * netEnchant(theItem) / FP_FACTOR;
armorValue /= 10;
} else {
new = armorValueIfUnenchanted(theItem);
armorValue = armorValueIfUnenchanted(theItem);
}

new = max(0, new);
armorValue = max(0, armorValue);

sprintf(buf2, "Wearing the %s%s will result in an armor rating of %s%i%s. ",
sprintf(buf2, "Wearing the %s%s will result in an armor rating of %s%g%s. ",
theName,
((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) ? "" : ", assuming it has no hidden properties,",
(new > displayedArmorValue() ? goodColorEscape : (new < displayedArmorValue() ? badColorEscape : whiteColorEscape)),
new, whiteColorEscape);
(armorValue > displayedArmorValue() ? goodColorEscape : (armorValue < displayedArmorValue() ? badColorEscape : whiteColorEscape)),
armorValue, whiteColorEscape);
}
strcat(buf, buf2);
}
Expand Down Expand Up @@ -3099,16 +3099,16 @@ void updateEncumbrance() {
}

// Estimates the armor value of the given item, assuming the item is unenchanted.
short armorValueIfUnenchanted(item *theItem) {
short averageValue = (armorTable[theItem->kind].range.upperBound + armorTable[theItem->kind].range.lowerBound) / 2;
short strengthAdjusted = averageValue + 10 * strengthModifier(theItem) / FP_FACTOR;
float armorValueIfUnenchanted(item *theItem) {
float averageValue = (armorTable[theItem->kind].range.upperBound + armorTable[theItem->kind].range.lowerBound) / 2;
float strengthAdjusted = averageValue + 10 * strengthModifier(theItem) / FP_FACTOR;
return max(0, strengthAdjusted / 10);
}

// Calculates the armor value to display to the player (estimated if the item is unidentified).
short displayedArmorValue() {
float displayedArmorValue() {
if (!rogue.armor || (rogue.armor->flags & ITEM_IDENTIFIED)) {
return player.info.defense / 10;
return ((float) player.info.defense) / 10;
} else {
return armorValueIfUnenchanted(rogue.armor);
}
Expand Down
16 changes: 15 additions & 1 deletion src/brogue/PowerTables.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,21 @@ fixpt defenseFraction(fixpt netDefense) {
469, 453, 439, 425, 411, 398, 385, 373, 361, 349, 338, 327, 316, 306, 296, 287, 277, 268, 260, 251, 243, 235, 228, 221, 213, 207,
200, 193, 187, 181, 175, 170, 164, 159, 154, 149, 144, 139, 135, 130, 126, 122, 118, 114, 111, 107, 104, 100, 97, 94};

short idx = clamp(netDefense * 4 / 10 / FP_FACTOR + 80, 0, LAST_INDEX(POW_DEFENSE_FRACTION));
/* Examples of what this code does for different armor values:
(Using floating point instead of fixed point, and using small armor values, for clarity)
An armor value of 1.5 results in a netDefense is 15.0.
An armor value of 1.75 results in a netDefense of 17.0 (the 0.5 is lost before this function is called).
It multiplies by 4, so the last decimal place would be zero if it weren't for the 0.5 being lost (as above).
15.0 -> 60.0; 17.0 -> 68.0 (this would be 70 if not for the truncation)
It divides by 10: 60.0 -> 6.0, 68.0 -> 6.8
It adds 0.5 to compensate for the truncation: 6.0 -> 6.5; 6.8 -> 7.3
This could add anywhere from 0.2 to 0.99, but 0.5 seems like the least arbitrary choice.
Without this, the step below would round both 6.0 and 6.8 down to 6.
It converts to an integer (which rounds towards zero): 6.5 -> 6; 7.3 -> 7
It adds 80 (because some of the entries are for negative armor values) and clamps to the size of the table
This is the index into the table above.
*/
short idx = clamp((netDefense * 4 / 10 + FP_FACTOR / 2) / FP_FACTOR + 80, 0, LAST_INDEX(POW_DEFENSE_FRACTION));
return POW_DEFENSE_FRACTION[idx];
}

Expand Down
4 changes: 2 additions & 2 deletions src/brogue/Rogue.h
Original file line number Diff line number Diff line change
Expand Up @@ -3181,8 +3181,8 @@ extern "C" {
short chooseKind(itemTable *theTable, short numKinds);
item *makeItemInto(item *theItem, unsigned long itemCategory, short itemKind);
void updateEncumbrance();
short displayedArmorValue();
short armorValueIfUnenchanted(item *theItem);
float displayedArmorValue();
float armorValueIfUnenchanted(item *theItem);
void strengthCheck(item *theItem, boolean noisy);
void recalculateEquipmentBonuses();
boolean equipItem(item *theItem, boolean force, item *unequipHint);
Expand Down

0 comments on commit 377e222

Please sign in to comment.