Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions config.lua.dist
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ blackSkulledDeathMana = 0
fieldOwnershipDuration = 5 * 1000
loginProtectionPeriod = 10 * 1000

-- Expert PvP
-- NOTE: toggleExpertPvp enables the PvP frames, similar to Tibia RL.
toggleExpertPvp = true
canWalkThroughOtherPlayers = false
canWalkThroughMagicWalls = false

-- Guilds
-- ingameGuildManagement: set true to enable in-game guild commands.
-- guildWarsDefaultFrags: Default frags for guild war invitations if not specified.
Expand Down
15 changes: 0 additions & 15 deletions data/modules/lib/modules.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,3 @@ function addPlayerEvent(callable, delay, playerId, ...)
end
end, delay, callable, player.uid, ...)
end

--[[
function Player.updateFightModes(self)
local msg = NetworkMessage()

msg:addByte(0xA7)

msg:addByte(self:getFightMode())
msg:addByte(self:getChaseMode())
msg:addByte(self:getSecureMode() and 1 or 0)
msg:addByte(self:getPvpMode())

msg:sendToPlayer(self)
end
]]
3 changes: 3 additions & 0 deletions src/config/config_enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,9 @@ enum ConfigKey_t : uint16_t {
TOGGLE_GUILD_WARS,
GUILD_WARS_MINIMUM_FRAGS,
GUILD_WARS_DEFAULT_FRAGS,
TOGGLE_EXPERT_PVP,
EXPERT_PVP_CANWALKTHROUGHOTHERPLAYERS,
EXPERT_PVP_CANWALKTHROUGHMAGICWALLS,
INGAME_GUILD_MANAGEMENT,
LEVEL_TO_FORM_GUILD,
CREATE_GUILD_ONLY_PREMIUM,
Expand Down
3 changes: 3 additions & 0 deletions src/config/configmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ bool ConfigManager::load() {
loadBoolConfig(L, TOGGLE_GUILDHALL_NEED_GUILD, "toggleGuildHallNeedGuild", true);
loadBoolConfig(L, TOGGLE_MAX_CONNECTIONS_BY_IP, "toggleMaxConnectionsByIP", false);
loadBoolConfig(L, TOGGLE_GUILD_WARS, "toggleGuildWars", false);
loadBoolConfig(L, TOGGLE_EXPERT_PVP, "toggleExpertPvp", false);
loadBoolConfig(L, EXPERT_PVP_CANWALKTHROUGHOTHERPLAYERS, "canWalkThroughOtherPlayers", false);
loadBoolConfig(L, EXPERT_PVP_CANWALKTHROUGHMAGICWALLS, "canWalkThroughMagicWalls", false);
loadBoolConfig(L, INGAME_GUILD_MANAGEMENT, "ingameGuildManagement", true);
loadBoolConfig(L, CREATE_GUILD_ONLY_PREMIUM, "createGuildOnlyPremium", true);

Expand Down
42 changes: 40 additions & 2 deletions src/creatures/combat/combat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,8 @@ ReturnValue Combat::canDoCombat(const std::shared_ptr<Creature> &attacker, const

if (isProtected(attackerPlayer, targetPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
} else if (!attackerPlayer->canCombat(targetPlayer)) {
return RETURNVALUE_ADJUSTYOURCOMBAT;
}

// nopvp-zone
Expand Down Expand Up @@ -433,6 +435,8 @@ ReturnValue Combat::canDoCombat(const std::shared_ptr<Creature> &attacker, const

if (isProtected(masterAttackerPlayer, targetPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
} else if (!masterAttackerPlayer->canCombat(targetPlayer)) {
return RETURNVALUE_ADJUSTYOURCOMBAT;
}
}
}
Expand All @@ -452,14 +456,30 @@ ReturnValue Combat::canDoCombat(const std::shared_ptr<Creature> &attacker, const
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}

if (target->isSummon() && targetMasterPlayer && target->getZoneType() == ZONE_NOPVP) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
if (g_game().getOwnerPlayer(target)) {
if (target->getZoneType() == ZONE_NOPVP) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
} else if (g_configManager().getBoolean(TOGGLE_EXPERT_PVP) && isProtected(attackerPlayer, targetPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
} else if (!attackerPlayer->canCombat(target)) {
return RETURNVALUE_ADJUSTYOURCOMBAT;
}
}
} else if (attackerMonster) {
if ((!targetMaster || !targetMasterPlayer) && attacker->getFaction() == FACTION_DEFAULT) {
if (!attackerMaster || !masterAttackerPlayer) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
}
} else if (g_configManager().getBoolean(TOGGLE_EXPERT_PVP)) {
if (g_game().getOwnerPlayer(target)) {
if (target->getZoneType() == ZONE_NOPVP) {
return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE;
} else if (isProtected(attackerPlayer, targetPlayer)) {
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;
} else if (!attackerPlayer->canCombat(target)) {
return RETURNVALUE_ADJUSTYOURCOMBAT;
}
}
}
}
} else if (target && target->getNpc()) {
Expand Down Expand Up @@ -2503,6 +2523,11 @@ void AreaCombat::setupExtArea(const std::list<uint32_t> &list, uint32_t rows) {
//**********************************************************//

void MagicField::onStepInField(const std::shared_ptr<Creature> &creature) {
const auto &target = g_game().getOwnerPlayer(creature);
if (target && !isAggressive(target)) {
return;
}

// remove magic walls/wild growth
if ((!isBlocking() && g_game().getWorldType() == WORLDTYPE_OPTIONAL && id == ITEM_MAGICWALL_SAFE) || id == ITEM_WILDGROWTH_SAFE) {
if (!creature->isInGhostMode()) {
Expand Down Expand Up @@ -2757,6 +2782,19 @@ int32_t MagicField::getDamage() const {
return 0;
}

bool MagicField::isAggressive(const std::shared_ptr<Player> &player) const {
if (!g_configManager().getBoolean(TOGGLE_EXPERT_PVP) && g_configManager().getBoolean(EXPERT_PVP_CANWALKTHROUGHMAGICWALLS)) {
return true;
}

const auto &caster = g_game().getOwnerPlayer(getOwnerId());
if (!caster || pvpMode == PVP_MODE_RED_FIST) {
return true;
}

return caster->isAggressiveCreature(player, pvpMode == PVP_MODE_WHITE_HAND, createTime) || pvpMode == PVP_MODE_YELLOW_HAND && player->getSkull() != SKULL_NONE;
}

MatrixArea::MatrixArea(uint32_t initRows, uint32_t initCols) :
centerX(0), centerY(0), rows(initRows), cols(initCols) {
data_ = new bool*[rows];
Expand Down
3 changes: 3 additions & 0 deletions src/creatures/combat/combat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,9 @@ class MagicField final : public Item {
CombatType_t getCombatType() const;
int32_t getDamage() const;
void onStepInField(const std::shared_ptr<Creature> &creature);
bool isAggressive(const std::shared_ptr<Player> &player) const;

PvpMode_t pvpMode = PVP_MODE_DOVE;

private:
int64_t createTime;
Expand Down
2 changes: 1 addition & 1 deletion src/creatures/combat/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1850,7 +1850,7 @@ bool ConditionDamage::doDamage(const std::shared_ptr<Creature> &creature, int32_
}

if (!creature->isAttackable() || Combat::canDoCombat(attacker, creature, damage.primary.type != COMBAT_HEALING) != RETURNVALUE_NOERROR) {
if (!creature->isInGhostMode() && !creature->getNpc()) {
if (!creature->isInGhostMode() && !creature->getNpc() && !g_configManager().getBoolean(TOGGLE_EXPERT_PVP)) {
g_game().addMagicEffect(creature->getPosition(), CONST_ME_POFF);
}
return false;
Expand Down
7 changes: 6 additions & 1 deletion src/creatures/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,12 @@ void Creature::onDeath() {
const uint64_t gainExp = getGainedExperience(attacker);
const auto &attackerMaster = attacker->getMaster() ? attacker->getMaster() : attacker;
if (auto attackerPlayer = attackerMaster->getPlayer()) {
attackerPlayer->removeAttacked(getPlayer());
if (auto thisPlayer = getPlayer()) {
attackerPlayer->removeAttacked(thisPlayer);
thisPlayer->removeAttackedBy(attackerPlayer);
}

g_game().updateCreatureSquare(attackerPlayer);

const auto &party = attackerPlayer->getParty();
killers.insert(attackerPlayer);
Expand Down
Loading