示例#1
0
/**
 * 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;
	}
}
示例#2
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;
}