示例#1
0
ReturnValue Combat::canTargetCreature(const PlayerP& player, const CreatureP& target)
{
	if(player == target)
		return RET_YOUMAYNOTATTACKTHISPLAYER;

	CreatureEventList targetEvents = player->getCreatureEvents(CREATURE_EVENT_TARGET);

	bool deny = false;
	for(CreatureEventList::iterator it = targetEvents.begin(); it != targetEvents.end(); ++it)
	{
		if(!(*it)->executeTarget(player, target))
			deny = true;
	}

	if(deny)
		return RET_DONTSHOWMESSAGE;

	if(!player->hasFlag(PlayerFlag_IgnoreProtectionZone))
	{
		if(player->getZone() == ZONE_PROTECTION)
			return RET_YOUMAYNOTATTACKAPERSONWHILEINPROTECTIONZONE;

		if(target->getZone() == ZONE_PROTECTION)
			return RET_YOUMAYNOTATTACKAPERSONINPROTECTIONZONE;

		const Monster* targetMonster = target->getMonster();
		if(target->getPlayer() || (targetMonster != nullptr && targetMonster->getMaster() && targetMonster->getMaster()->getPlayer()))
		{
			if(player->getZone() == ZONE_NOPVP)
				return RET_ACTIONNOTPERMITTEDINANOPVPZONE;

			if(target->getZone() == ZONE_NOPVP)
				return RET_YOUMAYNOTATTACKAPERSONINPROTECTIONZONE;
		}
	}

	if(player->hasFlag(PlayerFlag_CannotUseCombat) || !target->isAttackable())
		return target->getPlayer() ? RET_YOUMAYNOTATTACKTHISPLAYER : RET_YOUMAYNOTATTACKTHISCREATURE;

	if(target->getPlayer() && !Combat::isInPvpZone(*player, *target) && player->getSkullClient(target->getPlayer()) == SKULL_NONE)
	{
		if(player->getSecureMode() == SECUREMODE_ON)
			return RET_TURNSECUREMODETOATTACKUNMARKEDPLAYERS;

		if(player->getSkull() == SKULL_BLACK)
			return RET_YOUMAYNOTATTACKTHISPLAYER;
	}

	return canDoCombat(player, target);
}
示例#2
0
void Combat::CombatFunc(Creature* caster, const Position& pos, const AreaCombat* area, const CombatParams& params, COMBATFUNC func, void* data)
{
	std::list<Tile*> tileList;

	if (caster) {
		getCombatArea(caster->getPosition(), pos, area, tileList);
	} else {
		getCombatArea(pos, pos, area, tileList);
	}

	SpectatorVec list;
	uint32_t maxX = 0;
	uint32_t maxY = 0;
	uint32_t diff;

	//calculate the max viewable range
	for (Tile* tile : tileList) {
		const Position& tilePos = tile->getPosition();

		diff = Position::getDistanceX(tilePos, pos);
		if (diff > maxX) {
			maxX = diff;
		}

		diff = Position::getDistanceY(tilePos, pos);
		if (diff > maxY) {
			maxY = diff;
		}
	}

	const int32_t rangeX = maxX + Map::maxViewportX;
	const int32_t rangeY = maxY + Map::maxViewportY;
	g_game.getSpectators(list, pos, true, true, rangeX, rangeX, rangeY, rangeY);

	for (Tile* tile : tileList) {
		if (canDoCombat(caster, tile, params.isAggressive) != RET_NOERROR) {
			continue;
		}

		if (CreatureVector* creatures = tile->getCreatures()) {
			const Creature* topCreature = tile->getTopCreature();
			for (Creature* creature : *creatures) {
				if (params.targetCasterOrTopMost) {
					if (caster && caster->getTile() == tile) {
						if (creature != caster) {
							continue;
						}
					} else if (creature != topCreature) {
						continue;
					}
				}

				if (!params.isAggressive || (caster != creature && Combat::canDoCombat(caster, creature) == RET_NOERROR)) {
					func(caster, creature, params, data);
					if (params.targetCallback) {
						params.targetCallback->onTargetCombat(caster, creature);
					}

					if (params.targetCasterOrTopMost) {
						break;
					}
				}
			}
		}
		combatTileEffects(list, caster, tile, params);
	}
	postCombatEffects(caster, pos, params);
}
示例#3
0
void Combat::CombatFunc(Creature* caster, const Position& pos,
	const AreaCombat* area, const CombatParams& params, COMBATFUNC func, void* data)
{
	std::list<Tile*> tileList;

	if(caster)
		getCombatArea(caster->getPosition(), pos, area, tileList);
	else
		getCombatArea(pos, pos, area, tileList);

	SpectatorVec list;
	uint32_t maxX = 0;
	uint32_t maxY = 0;
	uint32_t diff;

	//calculate the max viewable range
	for(std::list<Tile*>::iterator it = tileList.begin(); it != tileList.end(); ++it)
	{
		diff = std::abs((*it)->getPosition().x - pos.x);
		if(diff > maxX)
			maxX = diff;

		diff = std::abs((*it)->getPosition().y - pos.y);
		if(diff > maxY)
			maxY = diff;
	}

	g_game.getSpectators(list, pos, false, true, maxX + Map::maxViewportX, maxX + Map::maxViewportX,
		maxY + Map::maxViewportY, maxY + Map::maxViewportY);

	for(std::list<Tile*>::iterator it = tileList.begin(); it != tileList.end(); ++it)
	{
		Tile* iter_tile = *it;
		bool bContinue = true;
		if(canDoCombat(caster, iter_tile, params.isAggressive) == RET_NOERROR)
		{
			if(iter_tile->getCreatures())
			{
				for(CreatureVector::iterator cit = iter_tile->getCreatures()->begin(),
					cend = iter_tile->getCreatures()->end();
					bContinue && cit != cend; ++cit)
				{
					if(params.targetCasterOrTopMost)
					{
						if(caster && caster->getTile() == iter_tile)
						{
							if(*cit == caster)
								bContinue = false;
						}
						else if(*cit == iter_tile->getTopCreature())
							bContinue = false;

						if(bContinue)
							continue;
					}

					if(!params.isAggressive || (caster != *cit && Combat::canDoCombat(caster, *cit) == RET_NOERROR))
					{
						func(caster, *cit, params, data);
						if(params.targetCallback)
							params.targetCallback->onTargetCombat(caster, *cit);
					}
				}
			}
			combatTileEffects(list, caster, iter_tile, params);
		}
	}
	postCombatEffects(caster, pos, params);
}
示例#4
0
void Combat::CombatFunc(const CreatureP& caster, const Position& pos, const CombatArea* area,
	const CombatParams& params, COMBATFUNC func, void* data)
{
	std::list<Tile*> tileList;
	if(caster)
		getCombatArea(caster->getPosition(), pos, area, tileList);
	else
		getCombatArea(pos, pos, area, tileList);

	Combat2Var* var = (Combat2Var*)data;
	if(var && !params.differentAreaDamage)
		var->change = random_range(var->minChange, var->maxChange, DISTRO_NORMAL);

	uint32_t maxX = 0, maxY = 0, diff;
	//calculate the max viewable range
	for(std::list<Tile*>::iterator it = tileList.begin(); it != tileList.end(); ++it)
	{
		diff = std::abs((*it)->getPosition().x - pos.x);
		if(diff > maxX)
			maxX = diff;

		diff = std::abs((*it)->getPosition().y - pos.y);
		if(diff > maxY)
			maxY = diff;
	}

	SpectatorList list;
	server.game().getSpectators(list, pos, false, true, maxX + Map::maxViewportX, maxX + Map::maxViewportX,
		maxY + Map::maxViewportY, maxY + Map::maxViewportY);

	MonsterP monsterCaster = caster->getMonster();

	Tile* tile = nullptr;
	for(std::list<Tile*>::iterator it = tileList.begin(); it != tileList.end(); ++it)
	{
		if(!(tile = (*it)) || canDoCombat(caster, (*it), params.isAggressive) != RET_NOERROR)
			continue;

		bool skip = true;

		if (tile->getCreatures() != nullptr) {
			auto creatures = *tile->getCreatures();
			for (auto cit = creatures.begin(), cend = creatures.end(); skip && cit != cend; ++cit)
			{
				if(params.targetPlayersOrSummons && !(*cit)->getPlayer() && !(*cit)->hasController())
					continue;

				if(params.targetCasterOrTopMost)
				{
					if(caster && caster->getTile() == tile)
					{
						if((*cit) == caster)
							skip = false;
					}
					else if((*cit) == tile->getTopCreature())
						skip = false;

					if(skip)
						continue;
				}

				if(!params.isAggressive || (caster != (*cit) && Combat::canDoCombat(caster, (*cit).get()) == RET_NOERROR))
				{
					func(caster, *cit, params, (void*)var);
					if(params.targetCallback)
						params.targetCallback->onTargetCombat(caster, *cit);
				}
			}
		}

		combatTileEffects(list, caster, tile, params);
	}

	postCombatEffects(caster, pos, params);
}
示例#5
0
void Combat::CombatFunc(Creature* caster, const Position& pos, const CombatArea* area,
	const CombatParams& params, COMBATFUNC func, void* data)
{
	std::list<Tile*> tileList;
	if(caster)
		getCombatArea(caster->getPosition(), pos, area, tileList);
	else
		getCombatArea(pos, pos, area, tileList);

	Combat2Var* var = (Combat2Var*)data;
	if(var && !params.differentAreaDamage)
		var->change = random_range(var->minChange, var->maxChange, DISTRO_NORMAL);

	uint32_t maxX = 0, maxY = 0, diff;
	//calculate the max viewable range
	for(std::list<Tile*>::iterator it = tileList.begin(); it != tileList.end(); ++it)
	{
		diff = std::abs((*it)->getPosition().x - pos.x);
		if(diff > maxX)
			maxX = diff;

		diff = std::abs((*it)->getPosition().y - pos.y);
		if(diff > maxY)
			maxY = diff;
	}

	SpectatorVec list;
	g_game.getSpectators(list, pos, false, true, maxX + Map::maxViewportX, maxX + Map::maxViewportX,
		maxY + Map::maxViewportY, maxY + Map::maxViewportY);

	Tile* tile = NULL;
	for(std::list<Tile*>::iterator it = tileList.begin(); it != tileList.end(); ++it)
	{
		if(!(tile = (*it)) || canDoCombat(caster, (*it), params.isAggressive, params.itemId != 0) != RET_NOERROR)
			continue;

		bool skip = true;
		if(CreatureVector* creatures = tile->getCreatures())
		{
			for(CreatureVector::iterator cit = creatures->begin(), cend = creatures->end(); skip && cit != cend; ++cit)
			{
				if(params.targetPlayersOrSummons && !(*cit)->getPlayer() && !(*cit)->isPlayerSummon())
					continue;

				if(params.targetCasterOrTopMost)
				{
					if(!g_config.getBool(ConfigManager::RUNES_HIT_TOP_CREATURE) && (caster && caster->getTile() == tile))
					{
						if((*cit) == caster)
							skip = false;
					}
					else if((*cit) == tile->getTopCreature())
						skip = false;

					if(skip)
						continue;
				}

				if(!params.isAggressive || (caster != (*cit) && Combat::canDoCombat(caster, (*cit), true) == RET_NOERROR))
				{
					func(caster, (*cit), params, (void*)var);
					if(params.targetCallback)
						params.targetCallback->onTargetCombat(caster, (*cit));
				}
			}
		}

		combatTileEffects(list, caster, tile, params);
	}

	postCombatEffects(caster, pos, params);
}