/** * Calculate firing accuracy. * Formula = accuracyStat * weaponAccuracy * kneelingbonus(1.15) * one-handPenalty(0.8) * woundsPenalty(% health) * critWoundsPenalty (-10%/wound) * @param actionType * @param item * @return firing Accuracy */ double BattleUnit::getFiringAccuracy(BattleActionType actionType, BattleItem *item) const { double result = (double)(_unit->getFiringAccuracy() / 100.0); double weaponAcc = item->getRules()->getAccuracySnap(); if (actionType == BA_AIMEDSHOT) weaponAcc = item->getRules()->getAccuracyAimed(); if (actionType == BA_AUTOSHOT) weaponAcc = item->getRules()->getAccuracyAuto(); result *= (double)(weaponAcc/100.0); if (_kneeled) result *= 1.15; if (item->getRules()->getTwoHanded()) { // two handed weapon, means one hand should be empty if (getItem("STR_RIGHT_HAND") != 0 && getItem("STR_LEFT_HAND") != 0) { result *= 0.80; } } result *= ((double)_health/(double)_unit->getHealth()); result *= 1 + (-0.1*getFatalWounds()); return result; }
/** * Restore soldier morale */ void BattleUnit::painKillers () { if (!getFatalWounds() || !_needPainKiller) { return ; } _needPainKiller = false; int lostHealth = _unit->getHealth() - _health; _morale += lostHealth; }
/** * Prepare for a new turn. */ void BattleUnit::prepareNewTurn() { // recover TUs int TURecovery = _unit->getTimeUnits(); // Each fatal wound to the left or right leg reduces the soldier's TUs by 10%. TURecovery -= (TURecovery * (_fatalWounds[BODYPART_LEFTLEG]+_fatalWounds[BODYPART_RIGHTLEG] * 10))/100; setTimeUnits(TURecovery); // recover energy if (!isOut()) { int ENRecovery = _unit->getTimeUnits() / 3; // Each fatal wound to the body reduces the soldier's energy recovery by 10%. ENRecovery -= (_energy * (_fatalWounds[BODYPART_TORSO] * 10))/100; _energy += ENRecovery; if (_energy > _unit->getStamina()) _energy = _unit->getStamina(); } // suffer from fatal wounds _health -= getFatalWounds(); // suffer from fire if (_fire > 0) { _health -= RNG::generate(5, 10); _fire--; } if (_health < 0) _health = 0; // recover stun 1pt/turn if (_stunlevel > 0) stun(-1); if (!isOut()) { int chance = 100 - (2 * getMorale()); if (RNG::generate(1,100) <= chance) { int type = RNG::generate(0,100); _status = (type<=33?STATUS_BERSERK:STATUS_PANICKING); // 33% chance of berserk, panic can mean freeze or flee, but that is determined later } else { // succesfully avoided panic // increase bravery experience counter if (chance > 1) _expBravery++; } } _dontReselect = false; }