Ir para conteúdo

Featured Replies

Postado

Olá caros Tkanos, como colocar pra exp shared party em time ganhar 2x de exp?

Sei que é nas Sources em Party.cpp, alguem me dar uma luz?

Darei REP+

 

Party.cpp

Spoiler

/**
 * The Forgotten Server - a free and open-source MMORPG server emulator
 * Copyright (C) 2016  Mark Samman <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "otpch.h"

#include "party.h"
#include "game.h"
#include "configmanager.h"
#include "events.h"

extern Game g_game;
extern ConfigManager g_config;
extern Events* g_events;

Party::Party(Player* leader)
{
    extraExpRate = 0.20f;

    sharedExpActive = false;
    sharedExpEnabled = false;

    this->leader = leader;
    leader->setParty(this);
}

void Party::disband()
{
    if (!g_events->eventPartyOnDisband(this)) {
        return;
    }

    Player* currentLeader = leader;
    leader = nullptr;

    currentLeader->setParty(nullptr);
    currentLeader->sendClosePrivate(CHANNEL_PARTY);
    g_game.updatePlayerShield(currentLeader);
    g_game.updatePlayerHelpers(*currentLeader);
    currentLeader->sendCreatureSkull(currentLeader);
    currentLeader->sendTextMessage(MESSAGE_INFO_DESCR, "Your party has been disbanded.");

    for (Player* invitee : inviteList) {
        invitee->removePartyInvitation(this);
        currentLeader->sendCreatureShield(invitee);
    }
    inviteList.clear();

    for (Player* member : memberList) {
        member->setParty(nullptr);
        member->sendClosePrivate(CHANNEL_PARTY);
        member->sendTextMessage(MESSAGE_INFO_DESCR, "Your party has been disbanded.");
    }

    for (Player* member : memberList) {
        g_game.updatePlayerShield(member);

        for (Player* otherMember : memberList) {
            otherMember->sendCreatureSkull(member);
        }

        member->sendCreatureSkull(currentLeader);
        currentLeader->sendCreatureSkull(member);
        g_game.updatePlayerHelpers(*member);
    }
    memberList.clear();
    delete this;
}

bool Party::leaveParty(Player* player)
{
    if (!player) {
        return false;
    }

    if (player->getParty() != this && leader != player) {
        return false;
    }

    if (!g_events->eventPartyOnLeave(this, player)) {
        return false;
    }

    bool missingLeader = false;
    if (leader == player) {
        if (!memberList.empty()) {
            if (memberList.size() == 1 && inviteList.empty()) {
                missingLeader = true;
            } else {
                passPartyLeadership(memberList.front());
            }
        } else {
            missingLeader = true;
        }
    }

    //since we already passed the leadership, we remove the player from the list
    auto it = std::find(memberList.begin(), memberList.end(), player);
    if (it != memberList.end()) {
        memberList.erase(it);
    }

    player->setParty(nullptr);
    player->sendClosePrivate(CHANNEL_PARTY);
    g_game.updatePlayerShield(player);
    g_game.updatePlayerHelpers(*player);

    for (Player* member : memberList) {
        member->sendCreatureSkull(player);
        player->sendPlayerPartyIcons(member);
        g_game.updatePlayerHelpers(*member);
    }

    leader->sendCreatureSkull(player);
    player->sendCreatureSkull(player);
    player->sendPlayerPartyIcons(leader);

    player->sendTextMessage(MESSAGE_INFO_DESCR, "You have left the party.");

    updateSharedExperience();
    updateVocationsList();

    clearPlayerPoints(player);

    std::ostringstream ss;
    ss << player->getName() << " has left the party.";
    broadcastPartyMessage(MESSAGE_INFO_DESCR, ss.str());

    if (missingLeader || empty()) {
        disband();
    }

    return true;
}

bool Party::passPartyLeadership(Player* player)
{
    if (!player || leader == player || player->getParty() != this) {
        return false;
    }

    //Remove it before to broadcast the message correctly
    auto it = std::find(memberList.begin(), memberList.end(), player);
    if (it != memberList.end()) {
        memberList.erase(it);
    }

    std::ostringstream ss;
    ss << player->getName() << " is now the leader of the party.";
    broadcastPartyMessage(MESSAGE_INFO_DESCR, ss.str(), true);

    Player* oldLeader = leader;
    leader = player;

    memberList.insert(memberList.begin(), oldLeader);

    updateSharedExperience();

    for (Player* member : memberList) {
        member->sendCreatureShield(oldLeader);
        member->sendCreatureShield(leader);
    }

    for (Player* invitee : inviteList) {
        invitee->sendCreatureShield(oldLeader);
        invitee->sendCreatureShield(leader);
    }

    leader->sendCreatureShield(oldLeader);
    leader->sendCreatureShield(leader);

    player->sendTextMessage(MESSAGE_INFO_DESCR, "You are now the leader of the party.");
    return true;
}

bool Party::joinParty(Player& player)
{
    if (!g_events->eventPartyOnJoin(this, &player)) {
        return false;
    }

    auto it = std::find(inviteList.begin(), inviteList.end(), &player);
    if (it == inviteList.end()) {
        return false;
    }

    inviteList.erase(it);

    std::ostringstream ss;
    ss << player.getName() << " has joined the party.";
    broadcastPartyMessage(MESSAGE_INFO_DESCR, ss.str());

    player.setParty(this);

    g_game.updatePlayerShield(&player);

    for (Player* member : memberList) {
        member->sendCreatureSkull(&player);
        player.sendPlayerPartyIcons(member);
    }

    player.sendCreatureSkull(&player);
    leader->sendCreatureSkull(&player);
    player.sendPlayerPartyIcons(leader);

    memberList.push_back(&player);

    g_game.updatePlayerHelpers(player);

    player.removePartyInvitation(this);
    updateSharedExperience();
    updateVocationsList();

    const std::string& leaderName = leader->getName();
    ss.str(std::string());
    ss << "You have joined " << leaderName << "'" << (leaderName.back() == 's' ? "" : "s") <<
       " party. Open the party channel to communicate with your companions.";
    player.sendTextMessage(MESSAGE_INFO_DESCR, ss.str());
    return true;
}

bool Party::removeInvite(Player& player, bool removeFromPlayer/* = true*/)
{
    auto it = std::find(inviteList.begin(), inviteList.end(), &player);
    if (it == inviteList.end()) {
        return false;
    }

    inviteList.erase(it);

    leader->sendCreatureShield(&player);
    player.sendCreatureShield(leader);

    if (removeFromPlayer) {
        player.removePartyInvitation(this);
    }

    if (empty()) {
        disband();
    } else {
        for (Player* member : memberList) {
            g_game.updatePlayerHelpers(*member);
        }

        g_game.updatePlayerHelpers(*leader);
    }

    return true;
}

void Party::revokeInvitation(Player& player)
{
    std::ostringstream ss;
    ss << leader->getName() << " has revoked " << (leader->getSex() == PLAYERSEX_FEMALE ? "her" : "his") << " invitation.";
    player.sendTextMessage(MESSAGE_INFO_DESCR, ss.str());

    ss.str(std::string());
    ss << "Invitation for " << player.getName() << " has been revoked.";
    leader->sendTextMessage(MESSAGE_INFO_DESCR, ss.str());

    removeInvite(player);
}

bool Party::invitePlayer(Player& player)
{
    if (isPlayerInvited(&player)) {
        return false;
    }

    std::ostringstream ss;
    ss << player.getName() << " has been invited.";

    if (memberList.empty() && inviteList.empty()) {
        ss << " Open the party channel to communicate with your members.";
        g_game.updatePlayerShield(leader);
        leader->sendCreatureSkull(leader);
    }

    leader->sendTextMessage(MESSAGE_INFO_DESCR, ss.str());

    inviteList.push_back(&player);

    for (Player* member : memberList) {
        g_game.updatePlayerHelpers(*member);
    }
    g_game.updatePlayerHelpers(*leader);

    leader->sendCreatureShield(&player);
    player.sendCreatureShield(leader);

    player.addPartyInvitation(this);

    ss.str(std::string());
    ss << leader->getName() << " has invited you to " << (leader->getSex() == PLAYERSEX_FEMALE ? "her" : "his") << " party.";
    player.sendTextMessage(MESSAGE_INFO_DESCR, ss.str());
    return true;
}

bool Party::isPlayerInvited(const Player* player) const
{
    return std::find(inviteList.begin(), inviteList.end(), player) != inviteList.end();
}

void Party::updateAllPartyIcons()
{
    for (Player* member : memberList) {
        for (Player* otherMember : memberList) {
            member->sendCreatureShield(otherMember);
        }

        member->sendCreatureShield(leader);
        leader->sendCreatureShield(member);
    }
    leader->sendCreatureShield(leader);
}

void Party::broadcastPartyMessage(MessageClasses msgClass, const std::string& msg, bool sendToInvitations /*= false*/)
{
    for (Player* member : memberList) {
        member->sendTextMessage(msgClass, msg);
    }

    leader->sendTextMessage(msgClass, msg);

    if (sendToInvitations) {
        for (Player* invitee : inviteList) {
            invitee->sendTextMessage(msgClass, msg);
        }
    }
}

void Party::broadcastPartyLoot(const std::string& loot)
{
    leader->sendTextMessage(MESSAGE_INFO_DESCR, loot);

    for (Player* member : memberList) {
        member->sendTextMessage(MESSAGE_INFO_DESCR, loot);
    }
}

void Party::updateSharedExperience()
{
    if (sharedExpActive) {
        bool result = canEnableSharedExperience();
        if (result != sharedExpEnabled) {
            sharedExpEnabled = result;
            updateAllPartyIcons();
        }
    }
}

void Party::updateVocationsList()
{
    std::set<uint32_t> vocationIds;

    uint32_t vocationId = leader->getVocation()->getFromVocation();
    if (vocationId != VOCATION_NONE) {
        vocationIds.insert(vocationId);
    }

    for (const Player* member : memberList) {
        vocationId = member->getVocation()->getFromVocation();
        if (vocationId != VOCATION_NONE) {
            vocationIds.insert(vocationId);
        }
    }

    size_t size = vocationIds.size();
    if (size > 1) {
        extraExpRate = static_cast<float>(size * (10 + (size - 1) * 5)) / 100.f;
    } else {
        extraExpRate = 0.20f;
    }
}

bool Party::setSharedExperience(Player* player, bool sharedExpActive)
{
    if (!player || leader != player) {
        return false;
    }

    if (this->sharedExpActive == sharedExpActive) {
        return true;
    }

    this->sharedExpActive = sharedExpActive;

    if (sharedExpActive) {
        this->sharedExpEnabled = canEnableSharedExperience();

        if (this->sharedExpEnabled) {
            leader->sendTextMessage(MESSAGE_INFO_DESCR, "Shared Experience is now active.");
        } else {
            leader->sendTextMessage(MESSAGE_INFO_DESCR, "Shared Experience has been activated, but some members of your party are inactive.");
        }
    } else {
        leader->sendTextMessage(MESSAGE_INFO_DESCR, "Shared Experience has been deactivated.");
    }

    updateAllPartyIcons();
    return true;
}

void Party::shareExperience(uint64_t experience, Creature* source/* = nullptr*/)
{
    uint32_t shareExperience = static_cast<uint64_t>(std::ceil(((static_cast<double>(experience) / (memberList.size() + 1)) + (static_cast<double>(experience) * extraExpRate))));
    for (Player* member : memberList) {
        member->onGainSharedExperience(shareExperience, source);
    }
    leader->onGainSharedExperience(shareExperience, source);
}

bool Party::canUseSharedExperience(const Player* player) const
{
    if (memberList.empty()) {
        return false;
    }

    uint32_t highestLevel = leader->getLevel();
    for (Player* member : memberList) {
        if (member->getLevel() > highestLevel) {
            highestLevel = member->getLevel();
        }
    }

    uint32_t minLevel = static_cast<int32_t>(std::ceil((static_cast<float>(highestLevel) * 2) / 3));
    if (player->getLevel() < minLevel) {
        return false;
    }

    if (!Position::areInRange<30, 30, 1>(leader->getPosition(), player->getPosition())) {
        return false;
    }

    if (!player->hasFlag(PlayerFlag_NotGainInFight)) {
        //check if the player has healed/attacked anything recently
        auto it = ticksMap.find(player->getID());
        if (it == ticksMap.end()) {
            return false;
        }

        uint64_t timeDiff = OTSYS_TIME() - it->second;
        if (timeDiff > static_cast<uint64_t>(g_config.getNumber(ConfigManager::PZ_LOCKED))) {
            return false;
        }
    }
    return true;
}

bool Party::canEnableSharedExperience()
{
    if (!canUseSharedExperience(leader)) {
        return false;
    }

    for (Player* member : memberList) {
        if (!canUseSharedExperience(member)) {
            return false;
        }
    }
    return true;
}

void Party::updatePlayerTicks(Player* player, uint32_t points)
{
    if (points != 0 && !player->hasFlag(PlayerFlag_NotGainInFight)) {
        ticksMap[player->getID()] = OTSYS_TIME();
        updateSharedExperience();
    }
}

void Party::clearPlayerPoints(Player* player)
{
    auto it = ticksMap.find(player->getID());
    if (it != ticksMap.end()) {
        ticksMap.erase(it);
        updateSharedExperience();
    }
}

bool Party::canOpenCorpse(uint32_t ownerId) const
{
    if (Player* player = g_game.getPlayerByID(ownerId)) {
        return leader->getID() == ownerId || player->getParty() == this;
    }
    return false;
}
 

 

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

Quem Está Navegando 0

  • Nenhum usuário registrado visualizando esta página.

Estatísticas dos Fóruns

  • Tópicos 96.9k
  • Posts 519.7k

Informação Importante

Confirmação de Termo