コード例 #1
0
ファイル: weapons.cpp プロジェクト: CkyLua/tfs
bool WeaponMelee::useWeapon(Player* player, Item* item, Creature* target) const
{
	int32_t damageModifier = playerWeaponCheck(player, target);
	if(damageModifier == 0)
		return false;

	if(elementDamage != 0)
	{
		int32_t damage = getElementDamage(player, item);
		CombatParams eParams;
		eParams.combatType = elementType;
		eParams.isAggressive = true;
		eParams.useCharges = true;
		Combat::doCombatHealth(player, target, damage, damage, eParams);
	}
	return internalUseWeapon(player, item, target, damageModifier);
}
コード例 #2
0
ファイル: weapons.cpp プロジェクト: d33tah/forgottenserver
bool Weapon::internalUseWeapon(Player* player, Item* item, Creature* target, int32_t damageModifier) const
{
	if (m_scripted) {
		LuaVariant var;
		var.type = VARIANT_NUMBER;
		var.number = target->getID();
		executeUseWeapon(player, var);
	} else {
		CombatDamage damage;
		damage.primary.type = params.combatType;
		damage.primary.value = (getWeaponDamage(player, target, item) * damageModifier) / 100;
		damage.secondary.type = getElementType();
		damage.secondary.value = getElementDamage(player, target, item);
		Combat::doCombatHealth(player, target, damage, params);
	}

	onUsedAmmo(player, item, target->getTile());
	onUsedWeapon(player, item, target->getTile());
	return true;
}
コード例 #3
0
ファイル: weapons.cpp プロジェクト: heltz/maruim_server
void Weapon::internalUseWeapon(Player* player, Item* item, Creature* target, int32_t damageModifier) const
{
	if (m_scripted) {
		LuaVariant var;
		var.type = VARIANT_NUMBER;
		var.number = target->getID();
		executeUseWeapon(player, var);
	} else {
		CombatDamage damage;
		WeaponType_t weaponType = item->getWeaponType();
		if (weaponType == WEAPON_AMMO || weaponType == WEAPON_DISTANCE) {
			damage.origin = ORIGIN_RANGED;
		} else {
			damage.origin = ORIGIN_MELEE;
		}
		damage.primary.type = params.combatType;
		damage.primary.value = (getWeaponDamage(player, target, item) * damageModifier) / 100;
		damage.secondary.type = getElementType();
		damage.secondary.value = getElementDamage(player, target, item);
		Combat::doCombatHealth(player, target, damage, params);
	}

	onUsedWeapon(player, item, target->getTile());
}
コード例 #4
0
ファイル: weapons.cpp プロジェクト: bergvall/forgottenserver
bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) const
{
	int32_t damageModifier = playerWeaponCheck(player, target);

	if (damageModifier == 0) {
		return false;
	}

	int32_t chance;

	if (hitChance == 0) {
		//hit chance is based on distance to target and distance skill
		uint32_t skill = player->getSkill(SKILL_DIST, SKILL_LEVEL);
		const Position& playerPos = player->getPosition();
		const Position& targetPos = target->getPosition();
		uint32_t distance = std::max<uint32_t>(Position::getDistanceX(playerPos, targetPos), Position::getDistanceY(playerPos, targetPos));

		if (maxHitChance == 75) {
			//chance for one-handed weapons
			switch (distance) {
				case 1:
					chance = std::min<uint32_t>(skill, 74) + 1;
					break;
				case 2:
					chance = (uint32_t)((float)2.4 * std::min<uint32_t>(skill, 28)) + 8;
					break;
				case 3:
					chance = (uint32_t)((float)1.55 * std::min<uint32_t>(skill, 45)) + 6;
					break;
				case 4:
					chance = (uint32_t)((float)1.25 * std::min<uint32_t>(skill, 58)) + 3;
					break;
				case 5:
					chance = (uint32_t)((float)std::min<uint32_t>(skill, 74)) + 1;
					break;
				case 6:
					chance = (uint32_t)((float)0.8 * std::min<uint32_t>(skill, 90)) + 3;
					break;
				case 7:
					chance = (uint32_t)((float)0.7 * std::min<uint32_t>(skill, 104)) + 2;
					break;
				default:
					chance = hitChance;
					break;
			}
		} else if (maxHitChance == 90) {
			//formula for two-handed weapons
			switch (distance) {
				case 1:
					chance = (uint32_t)((float)1.2 * std::min<uint32_t>(skill, 74)) + 1;
					break;
				case 2:
					chance = (uint32_t)((float)3.2 * std::min<uint32_t>(skill, 28));
					break;
				case 3:
					chance = (uint32_t)((float)2.0 * std::min<uint32_t>(skill, 45));
					break;
				case 4:
					chance = (uint32_t)((float)1.55 * std::min<uint32_t>(skill, 58));
					break;
				case 5:
					chance = (uint32_t)((float)1.2 * std::min<uint32_t>(skill, 74)) + 1;
					break;
				case 6:
					chance = (uint32_t)((float)1.0 * std::min<uint32_t>(skill, 90));
					break;
				case 7:
					chance = (uint32_t)((float)1.0 * std::min<uint32_t>(skill, 90));
					break;
				default:
					chance = hitChance;
					break;
			}
		} else if (maxHitChance == 100) {
			switch (distance) {
				case 1:
					chance = (uint32_t)((float)1.35 * std::min<uint32_t>(skill, 73)) + 1;
					break;
				case 2:
					chance = (uint32_t)((float)3.2 * std::min<uint32_t>(skill, 30)) + 4;
					break;
				case 3:
					chance = (uint32_t)((float)2.05 * std::min<uint32_t>(skill, 48)) + 2;
					break;
				case 4:
					chance = (uint32_t)((float)1.5 * std::min<uint32_t>(skill, 65)) + 2;
					break;
				case 5:
					chance = (uint32_t)((float)1.35 * std::min<uint32_t>(skill, 73)) + 1;
					break;
				case 6:
					chance = (uint32_t)((float)1.2 * std::min<uint32_t>(skill, 87)) - 4;
					break;
				case 7:
					chance = (uint32_t)((float)1.1 * std::min<uint32_t>(skill, 90)) + 1;
					break;
				default:
					chance = hitChance;
					break;
			}
		} else {
			chance = maxHitChance;
		}
	} else {
		chance = hitChance;
	}

	if (item->getWeaponType() == WEAPON_AMMO) {
		Item* bow = player->getWeapon(true);
		if (bow && bow->getHitChance() != 0) {
			chance += bow->getHitChance();
		}
	}

	if (chance >= random_range(1, 100)) {
		if (elementDamage != 0) {
			int32_t damage = getElementDamage(player, target, item);
			CombatParams eParams;
			eParams.combatType = elementType;
			eParams.isAggressive = true;
			eParams.useCharges = true;
			Combat::doCombatHealth(player, target, damage, damage, eParams);
		}

		Weapon::internalUseWeapon(player, item, target, damageModifier);
	} else {
		//miss target
		Tile* destTile = target->getTile();

		if (!Position::areInRange<1, 1, 0>(player->getPosition(), target->getPosition())) {
			std::vector<std::pair<int32_t, int32_t>> destList;
			destList.push_back(std::make_pair(-1, -1));
			destList.push_back(std::make_pair(-1, 0));
			destList.push_back(std::make_pair(-1, 1));
			destList.push_back(std::make_pair(0, -1));
			destList.push_back(std::make_pair(0, 0));
			destList.push_back(std::make_pair(0, 1));
			destList.push_back(std::make_pair(1, -1));
			destList.push_back(std::make_pair(1, 0));
			destList.push_back(std::make_pair(1, 1));

			std::random_shuffle(destList.begin(), destList.end());

			Position destPos = target->getPosition();

			for (const auto& dir : destList) {
				Tile* tmpTile = g_game.getTile(destPos.x + dir.first, destPos.y + dir.second, destPos.z);

				// Blocking tiles or tiles without ground ain't valid targets for spears
				if (tmpTile && !tmpTile->hasProperty(IMMOVABLEBLOCKSOLID) && tmpTile->ground != NULL) {
					destTile = tmpTile;
					break;
				}
			}
		}

		Weapon::internalUseWeapon(player, item, destTile);
	}

	return true;
}