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); }
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); }
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); }
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); }
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); }