The Steed Stone is supposed to make it so that armor doesn't count toward your carry weight if you're wearing it. It accomplishes this by using a perk set to the "Mod Armor Weight" entry point. However, there are two bugs with the code that calls into that entry point -- specifically, the code that actually totals up your item weights to determine your carry weight.

The stack bug
The game accidentally makes that entire type of item weightless instead of just the one you're wearing. If you're carrying ten Glass Armors and you equip one, then all ten of them will become weightless. The problem stems from code that looks vaguely like this:

float item_weight = GetFormWeight(item);
if (item->formType == kFormType_Armor) {
   if (entry->IsWorn()) {
      CalculatePerkData(kEntryPoint_Mod_Armor_Weight, me, item, &item_weight);
      --count;
      this->totalWeight += item_weight;
   }
}
this->totalWeight += item_weight * count;


The CalculatePerkData function is responsible for handling all perk effects in the game. It takes two mandatory parameters -- the type of perk effect to calculate, and the character to calculate it on -- followed by additional parameters that vary for each perk effect. In this case, those parameters are the item type we're dealing with and a pointer to the item's weight variable. Because we're passing a pointer to that variable, the perk calculation can actually modify its value; this is how a "Mod Armor Weight" perk is able to adjust the weight of worn items.

But do you see the problem? Bethesda intended for us to use the modified item weight for the single one of the item that we're wearing, while using the original weight for the other copies of the item, but they unwittingly used the same variable for both. Once CalculatePerkData has altered the weight for one item in a stack, the rest of that stack is altered, too! The solution is to copy the item weight into a new variable and use that variable for the "Mod Armor Weight" behavior.

float item_weight = GetFormWeight(item);
if (item->formType == kFormType_Armor) {
if (entry->IsWorn()) {
float modified_weight = item_weight;
CalculatePerkData(kEntryPoint_Mod_Armor_Weight, me, item, &modified_weight);
--count;
this->totalWeight += modified_weight;
}
}
this->totalWeight += item_weight * count;


That's more or less what Cobb Bug Fixes patches the game to do.

Iron Shields are never affected
The function that computes your total carry weight has a second issue, and it has to do with how items are tracked in Bethesda RPGs. You might think that your inventory is a single list of items, but it's actually two: the list of items that you spawn with, and a second list of "container changes." When the game wants to compute your total weight, it has to go over both lists. The problem is that it only applies "Mod Armor Weight" perks for the second list -- the list of changes.

Did you know that you actually spawn with an Iron Shield, several potions, iron weapons, and a full set of iron armor? It's true. The game uses scripts to remove these items from you during the game's intro, but if you use the CenterOnCell debug command from the main menu, you can spawn in the world with these items. They're useful for testing and I imagine that's why they're there. But here's the trick: the iron armor is added to you as an "outfit," so the armor isn't technically a set of items that you spawn with, so much as it is a set of items that get added to you automatically immediately after you spawn. That Iron Shield, however, is in the list of items that you spawn with. This means that the game will never apply "Mod Armor Weight" perks to Iron Shields, because they're always in your list of spawning items, and the game only applies the perk to items that you haven't spawned with -- items that exist exclusively in the list of "container changes."

Cobb Bug Fixes addresses this by patching the behavior for items that you spawn with, to run the same perk behavior as items in the "container changes" list. You can actually see that behavior in the code excerpt above.

Article information

Added on

Written by

DavidJCobb

0 comments

  翻译: