Skip to content

Commit

Permalink
Update combat.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
kaleohanopahala authored Feb 10, 2025
1 parent ab32754 commit cc8c8c9
Showing 1 changed file with 70 additions and 65 deletions.
135 changes: 70 additions & 65 deletions src/creatures/combat/combat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,29 +251,49 @@ ReturnValue Combat::canTargetCreature(const std::shared_ptr<Player> &player, con
return canDoCombat(player, target, true);
}

bool Combat::isInPvpZone(const std::shared_ptr<Creature> &attacker, const std::shared_ptr<Creature> &target) {
return attacker->getZoneType() == ZONE_PVP && target->getZoneType() == ZONE_PVP;
}

bool Combat::isProtected(const std::shared_ptr<Player> &attacker, const std::shared_ptr<Player> &target) {
uint32_t protectionLevel = g_configManager().getNumber(PROTECTION_LEVEL);
if (target->getLevel() < protectionLevel || attacker->getLevel() < protectionLevel) {
return true;
}

if ((!attacker->getVocation()->canCombat() || !target->getVocation()->canCombat()) && (attacker->getVocationId() == VOCATION_NONE || target->getVocationId() == VOCATION_NONE)) {
return true;
}

if (attacker->getSkull() == SKULL_BLACK && attacker->getSkullClient(target) == SKULL_NONE) {
return true;
}

return false;
}

ReturnValue Combat::canDoCombat(const std::shared_ptr<Creature> &caster, const std::shared_ptr<Tile> &tile, bool aggressive) {
if (!tile) {
return RETURNVALUE_NOERROR;
}

if (!aggressive) {
return RETURNVALUE_NOERROR;
}

if (tile->hasProperty(CONST_PROP_BLOCKPROJECTILE)) {
bool canThrow = false;

if (const auto fieldList = tile->getItemList()) {
for (const auto &findfield : *fieldList) {
if (findfield && (findfield->getID() == ITEM_MAGICWALL || findfield->getID() == ITEM_MAGICWALL_SAFE)) {
canThrow = true;
break;
}
if (auto fieldList = tile->getItemList()) {
if (std::none_of(fieldList->begin(), fieldList->end(), [](const auto &item) {
return item && (item->getID() == ITEM_MAGICWALL || item->getID() == ITEM_MAGICWALL_SAFE);
})) {
return RETURNVALUE_CANNOTTHROW;
}
}

if (!canThrow) {
} else {
return RETURNVALUE_CANNOTTHROW;
}
}

if (aggressive && tile->hasFlag(TILESTATE_PROTECTIONZONE)) {
if (tile->hasFlag(TILESTATE_PROTECTIONZONE)) {
return RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE;
}

Expand All @@ -290,66 +310,61 @@ ReturnValue Combat::canDoCombat(const std::shared_ptr<Creature> &caster, const s
return RETURNVALUE_FIRSTGOUPSTAIRS;
}

if (const auto &player = caster->getPlayer()) {
if (auto player = caster->getPlayer()) {
if (player->hasFlag(PlayerFlags_t::IgnoreProtectionZone)) {
return RETURNVALUE_NOERROR;
}
}
}

ReturnValue ret = g_events().eventCreatureOnAreaCombat(caster, tile, aggressive);
if (ret == RETURNVALUE_NOERROR) {
ret = g_callbacks().checkCallbackWithReturnValue(EventCallback_t::creatureOnTargetCombat, &EventCallback::creatureOnAreaCombat, caster, tile, aggressive);
}
return ret;
}

bool Combat::isInPvpZone(const std::shared_ptr<Creature> &attacker, const std::shared_ptr<Creature> &target) {
return attacker->getZoneType() == ZONE_PVP && target->getZoneType() == ZONE_PVP;
}

bool Combat::isProtected(const std::shared_ptr<Player> &attacker, const std::shared_ptr<Player> &target) {
uint32_t protectionLevel = g_configManager().getNumber(PROTECTION_LEVEL);
if (target->getLevel() < protectionLevel || attacker->getLevel() < protectionLevel) {
return true;
ReturnValue Combat::canDoCombat(const std::shared_ptr<Creature> &attacker, const std::shared_ptr<Creature> &target, bool aggressive) {
if (!aggressive) {
return RETURNVALUE_NOERROR;
}

if ((!attacker->getVocation()->canCombat() || !target->getVocation()->canCombat()) && (attacker->getVocationId() == VOCATION_NONE || target->getVocationId() == VOCATION_NONE)) {
return true;
if (!target) {
return RETURNVALUE_NOERROR;
}

if (attacker->getSkull() == SKULL_BLACK && attacker->getSkullClient(target) == SKULL_NONE) {
return true;
if (target->isSummon() && target->getMaster() && target->getMaster()->getPlayer()) {
if (!isInPvpZone(attacker, target)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}
}

return false;
}
auto targetTile = target->getTile();
if (!targetTile) {
return RETURNVALUE_NOTENOUGHROOM;
}

ReturnValue Combat::canDoCombat(const std::shared_ptr<Creature> &attacker, const std::shared_ptr<Creature> &target, bool aggressive) {
if (!aggressive) {
return RETURNVALUE_NOERROR;
if (targetTile->hasProperty(CONST_PROP_BLOCKPROJECTILE)) {
return RETURNVALUE_NOTENOUGHROOM;
}

const auto &targetPlayer = target ? target->getPlayer() : nullptr;
if (target) {
const std::shared_ptr<Tile> &tile = target->getTile();
if (tile->hasProperty(CONST_PROP_BLOCKPROJECTILE)) {
return RETURNVALUE_NOTENOUGHROOM;
}
if (targetPlayer && tile->hasFlag(TILESTATE_PROTECTIONZONE)) {
const auto permittedOnPz = targetPlayer->hasPermittedConditionInPZ();
return permittedOnPz ? RETURNVALUE_NOERROR : RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE;
}
auto targetPlayer = target->getPlayer();
if (targetPlayer && targetTile->hasFlag(TILESTATE_PROTECTIONZONE)) {
return targetPlayer->hasPermittedConditionInPZ() ? RETURNVALUE_NOERROR
: RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE;
}

if (attacker) {
const auto &attackerMaster = attacker->getMaster();
const auto &attackerPlayer = attacker->getPlayer();
auto attackerMaster = attacker->getMaster();
auto attackerPlayer = attacker->getPlayer();

if (targetPlayer) {
if (targetPlayer->hasFlag(PlayerFlags_t::CannotBeAttacked)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}

const auto &targetPlayerTile = targetPlayer->getTile();
auto targetPlayerTile = targetPlayer->getTile();

if (attackerPlayer) {
if (attackerPlayer->hasFlag(PlayerFlags_t::CannotAttackPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
Expand All @@ -359,11 +374,11 @@ ReturnValue Combat::canDoCombat(const std::shared_ptr<Creature> &attacker, const
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}

// nopvp-zone
const auto &attackerTile = attackerPlayer->getTile();
auto attackerTile = attackerPlayer->getTile();
if (targetPlayerTile && targetPlayerTile->hasFlag(TILESTATE_NOPVPZONE)) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
} else if (attackerTile && attackerTile->hasFlag(TILESTATE_NOPVPZONE) && targetPlayerTile && !targetPlayerTile->hasFlag(TILESTATE_NOPVPZONE | TILESTATE_PROTECTIONZONE)) {
}
if (attackerTile && attackerTile->hasFlag(TILESTATE_NOPVPZONE) && targetPlayerTile && !targetPlayerTile->hasFlag(TILESTATE_NOPVPZONE | TILESTATE_PROTECTIONZONE)) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
}

Expand All @@ -373,15 +388,13 @@ ReturnValue Combat::canDoCombat(const std::shared_ptr<Creature> &attacker, const
}

if (attackerMaster) {
if (const auto &masterAttackerPlayer = attackerMaster->getPlayer()) {
if (auto masterAttackerPlayer = attackerMaster->getPlayer()) {
if (masterAttackerPlayer->hasFlag(PlayerFlags_t::CannotAttackPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}

if (targetPlayerTile && targetPlayerTile->hasFlag(TILESTATE_NOPVPZONE)) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
}

if (isProtected(masterAttackerPlayer, targetPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}
Expand All @@ -393,7 +406,7 @@ ReturnValue Combat::canDoCombat(const std::shared_ptr<Creature> &attacker, const
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}
}
} else if (target && target->getMonster()) {
} else if (target->getMonster()) {
if (attacker->getFaction() != FACTION_DEFAULT && attacker->getFaction() != FACTION_PLAYER && attacker->getMonster() && !attacker->getMonster()->isEnemyFaction(target->getFaction())) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}
Expand All @@ -403,38 +416,30 @@ ReturnValue Combat::canDoCombat(const std::shared_ptr<Creature> &attacker, const
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}

if (target->isSummon() && target->getMaster()->getPlayer() && target->getZoneType() == ZONE_NOPVP) {
if (target->isSummon() && target->getMaster() && target->getMaster()->getPlayer() && target->getZoneType() == ZONE_NOPVP) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
}
} else if (attacker->getMonster()) {
const auto &targetMaster = target->getMaster();

auto targetMaster = target->getMaster();
if ((!targetMaster || !targetMaster->getPlayer()) && attacker->getFaction() == FACTION_DEFAULT) {
if (!attackerMaster || !attackerMaster->getPlayer()) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}
}
}
} else if (target && target->getNpc()) {
} else if (target->getNpc()) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}

if (g_game().getWorldType() == WORLD_TYPE_NO_PVP) {
if (attacker->getPlayer() || (attackerMaster && attackerMaster->getPlayer())) {
if (targetPlayer) {
if (!isInPvpZone(attacker, target)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}
}

if (target && target->isSummon() && target->getMaster()->getPlayer()) {
if (!isInPvpZone(attacker, target)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}
if (attackerPlayer || (attackerMaster && attackerMaster->getPlayer())) {
if (targetPlayer && !isInPvpZone(attacker, target)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}
}
}
}

ReturnValue ret = g_events().eventCreatureOnTargetCombat(attacker, target);
if (ret == RETURNVALUE_NOERROR) {
ret = g_callbacks().checkCallbackWithReturnValue(EventCallback_t::creatureOnTargetCombat, &EventCallback::creatureOnTargetCombat, attacker, target);
Expand Down

0 comments on commit cc8c8c9

Please sign in to comment.