/** * Do an amount of damage. * @param position The position defines which part of armor and/or bodypart is hit. * @param power */ void BattleUnit::damage(Position position, int power) { int damage; UnitSide side; int impactheight; UnitBodyPart bodypart; if (power <= 0) { return; } if (position == Position(0, 0, 0)) { side = SIDE_UNDER; } else { // normalize x and y int x = 8, y = 8; switch(_direction) { case 0: // heading north, all is the same x = position.x; y = position.y; break; case 1: // somewhere in between 0 and 2 x = (position.x + (15 - position.y))/2; y = (position.y + position.x)/2; break; case 2: // heading east x = 15 - position.y; y = position.x; break; case 3: x = ((15 - position.y) + (15 - position.x))/2; y = (position.x + (15 - position.y))/2; break; case 4: // heading south, both axis inversed x = 15 - position.x; y = 15 - position.y; break; case 5: x = ((15 - position.x) + position.y)/2; y = ((15 - position.y) + (15 - position.x))/2; break; case 6: // heading west x = position.y; y = 15 - position.x; break; case 7: x = (position.y + position.x)/2; y = ((15 - position.x) + position.y)/2; break; } // determine side if (y > 9) side = SIDE_FRONT; else if (y < 6) side = SIDE_REAR; else if (x < 6) side = SIDE_LEFT; else if (x > 9) side = SIDE_RIGHT; else side = SIDE_FRONT; } impactheight = 10*position.z/getHeight(); if (impactheight > 4 && impactheight < 7) // torso { if (side == SIDE_LEFT) { bodypart = BODYPART_LEFTARM; }else if (side == SIDE_RIGHT) { bodypart = BODYPART_RIGHTARM; }else { bodypart = BODYPART_TORSO; } }else if (impactheight >= 7) //head { bodypart = BODYPART_HEAD; }else if (impactheight <=4) //legs { if (side == SIDE_LEFT || side == SIDE_FRONT) { bodypart = BODYPART_LEFTLEG; }else { bodypart = BODYPART_RIGHTLEG; } } damage = (power - getArmor(side)); if (damage > 0) { // fatal wounds if (RNG::generate(0,damage) > 2) _fatalWounds[bodypart] += RNG::generate(1,3); if (_fatalWounds[bodypart]) moraleChange(-_fatalWounds[bodypart]); // armor damage setArmor(getArmor(side) - (damage+5)/10, side); // health damage _health -= damage; if (_health < 0) _health = 0; } }
/** * Do an amount of damage. * @param position The position defines which part of armor and/or bodypart is hit. * @param power * @param type */ void BattleUnit::damage(Position position, int power, ItemDamageType type) { int damage; UnitSide side; int impactheight; UnitBodyPart bodypart; if (power <= 0) { return; } power *= _unit->getArmor()->getDamageModifier(type); if (type == DT_STUN) { _stunlevel += power; return; } if (position == Position(0, 0, 0)) { side = SIDE_UNDER; } else { // normalize x and y towards north int x = 8, y = 8; switch(_direction) { case 0: // heading north x = position.x; y = 15 - position.y; break; case 1: // somewhere in between 0 and 2 x = (position.x + position.y)/2; y = ((15 - position.y) + position.x)/2; break; case 2: // heading east x = 15 - position.y; y = 15 - position.x; break; case 3: x = (position.y + (15 - position.x))/2; y = (position.x + position.y)/2; break; case 4: // heading south x = 15 - position.x; y = position.y; break; case 5: x = ((15 - position.x) + (15 - position.y))/2; y = (position.y + (15 - position.x))/2; break; case 6: // heading west x = 15 - position.y; y = 15 - position.x; break; case 7: x = ((15 - position.y) + position.x)/2; y = ((15 - position.x) + (15 - position.y))/2; break; } // determine side if (y > 9) side = SIDE_FRONT; else if (y < 6) side = SIDE_REAR; else if (x < 6) side = SIDE_LEFT; else if (x > 9) side = SIDE_RIGHT; else side = SIDE_FRONT; } impactheight = 10*position.z/getHeight(); if (impactheight > 4 && impactheight < 7) // torso { if (side == SIDE_LEFT) { bodypart = BODYPART_LEFTARM; }else if (side == SIDE_RIGHT) { bodypart = BODYPART_RIGHTARM; }else { bodypart = BODYPART_TORSO; } }else if (impactheight >= 7) //head { bodypart = BODYPART_HEAD; }else if (impactheight <=4) //legs { if (side == SIDE_LEFT || side == SIDE_FRONT) { bodypart = BODYPART_LEFTLEG; }else { bodypart = BODYPART_RIGHTLEG; } } damage = (power - getArmor(side)); if (damage > 0) { if (_unit->isWoundable()) { // fatal wounds if (RNG::generate(0,damage) > 2) _fatalWounds[bodypart] += RNG::generate(1,3); if (_fatalWounds[bodypart]) moraleChange(-_fatalWounds[bodypart]); } // armor damage setArmor(getArmor(side) - (damage/10) - 1, side); // health damage _health -= damage; if (_health < 0) _health = 0; } _needPainKiller = true; }