How did you calculate this? I see Short Sword's StrengthModifier value (90) and Mithril's Strength value (200), but how did you find the formula (and the "/ 2000" part)?
It's in item.cpp, and the function goes a little something like this:
int item::GetStrengthValue() const
return long(GetStrengthModifier()) * GetMainMaterial()->GetStrengthValue() / 2000;
Regarding the bitchift operator, you are correct. If k = BlockSinceLastTurn and (1 << k) signifies a 'left-shift' operation, then this is the same as multiplying the first operand, i.e. 1, by 2^k. F. ex. 1*2^k: 1*2^2 = 4.
Really it's like this: 0001 << 2 = 0100 = 4, (in binary of course). All the bits are shifted two places to the left.
I agree with all your observations of the code you mentioned here:
if(RAND() % int(100 + WeaponToHitValue / BlockValue / (1 << BlocksSinceLastTurn) * (100 + Success)) < 100)
Double crap, I just realized I used the wrong number in WeaponToHitValue (I used Guss's block value instead of his THV). With his actual THV it becomes a 17% chance to block (but he still gets two chances at it). This seems... wrong.
Isn't the THV just the ToHitValue of the weapon/item?
With a little sourcediving I think this may just be the case. The THV flows through several functions before finding its use in the blocking function, but I think it originates inside bodypart.cpp. Specifically, the game checks to see if the character is wielding something, and then calculates a THV (of the item/arm) based on what is being wielded (or not).
Therefore, in bodypart.cpp we have this extremely interesting piece of code:
double arm::GetWieldedToHitValue() const
int HitStrength = GetWieldedHitStrength();
if(HitStrength <= 0)
citem* Wielded = GetWielded();
double Base = 2e-11
* Min(HitStrength, 10)
* (10000. / (1000 + Wielded->GetWeight()) + Wielded->GetTHVBonus());
double ThisToHit = GetAttribute(DEXTERITY) * sqrt(2.5 * Master->GetAttribute(PERCEPTION));
const arm* PairArm = GetPairArm();
if(PairArm && PairArm->IsUsable())
citem* PairWielded = PairArm->GetWielded();
if(Wielded->IsTwoHanded() && !Wielded->IsShield(Master))
return Base * (ThisToHit + PairArm->GetAttribute(DEXTERITY)
* sqrt(2.5 * Master->GetAttribute(PERCEPTION))) / 2;
else if(!Wielded->IsShield(Master) && !PairWielded->IsShield(Master))
return Base * ThisToHit / (1.0 + (500.0 + PairWielded->GetWeight())
/ (1000.0 + (Wielded->GetWeight() << 1)));
return Base * ThisToHit;
I think it calculates the THV and hence the WeaponTHV in the block. I think it bears resemblance to the parsing shown by Squash, no?
It's getting a bit late for me atm, but hopefully this provides more clues.