File indexing completed on 2024-05-19 05:40:48

0001 #include "updater/controller/playerupdater.h"
0002 #include "controller/gamecontroller.h"
0003 #include "data/player.h"
0004 #include "model/charactermodel.h"
0005 #include "network/connectionprofile.h"
0006 #include "worker/messagehelper.h"
0007 #include "worker/playermessagehelper.h"
0008 
0009 void addPlayerToModel(PlayerModel* model, NetworkMessageReader* msg)
0010 {
0011     Player* player= new Player();
0012     PlayerMessageHelper::readPlayer(*msg, player);
0013     model->addPlayer(player);
0014 }
0015 
0016 PlayerUpdater::PlayerUpdater(NetworkController* network, PlayerController* ctrl, QObject* parent)
0017     : QObject{parent}, m_ctrl(ctrl), m_networkCtrl(network)
0018 {
0019     ReceiveEvent::registerNetworkReceiver(NetMsg::UserCategory, this);
0020     ReceiveEvent::registerNetworkReceiver(NetMsg::PlayerCharacterCategory, this);
0021     auto model= m_ctrl->model();
0022 
0023     connect(model, &PlayerModel::playerJoin, this, &PlayerUpdater::updateNewPlayer);
0024     connect(model, &PlayerModel::playerLeft, this, &PlayerUpdater::playerLeft);
0025 }
0026 
0027 NetWorkReceiver::SendType PlayerUpdater::processMessage(NetworkMessageReader* msg)
0028 {
0029     NetWorkReceiver::SendType type= NetWorkReceiver::AllExceptSender;
0030     auto model= m_ctrl->model();
0031     if(msg->category() == NetMsg::UserCategory)
0032     {
0033         switch(msg->action())
0034         {
0035         case NetMsg::PlayerConnectionAction:
0036             addPlayerToModel(model, msg);
0037             break;
0038         case NetMsg::DelPlayerAction:
0039             model->removePlayer(model->playerById(MessageHelper::readPlayerId(*msg)));
0040             break;
0041         default:
0042             break;
0043         }
0044     }
0045     else if(msg->category() == NetMsg::PlayerCharacterCategory)
0046     {
0047         switch(msg->action())
0048         {
0049 
0050         case NetMsg::ChangePlayerPropertyAct:
0051         case NetMsg::ChangeCharacterPropertyAct:
0052             MessageHelper::updatePerson(*msg, model);
0053             break;
0054         default:
0055             break;
0056         }
0057     }
0058 
0059     return type;
0060 }
0061 
0062 void PlayerUpdater::setGameController(GameController* gameCtrl)
0063 {
0064     connect(gameCtrl, &GameController::connectedChanged, this,
0065             [this](bool b)
0066             {
0067                 if(b)
0068                 {
0069                     auto local= m_ctrl->localPlayer();
0070                     PlayerMessageHelper::sendOffPlayerInformations(local);
0071 
0072                     connect(local, &Player::avatarChanged, m_networkCtrl,
0073                             [this, local]()
0074                             {
0075                                 auto pro= m_networkCtrl->currentProfile();
0076                                 if(!pro)
0077                                     return;
0078                                 pro->setPlayerAvatar(local->avatar());
0079                             });
0080                     connect(local, &Player::nameChanged, m_networkCtrl,
0081                             [this, local]()
0082                             {
0083                                 auto pro= m_networkCtrl->currentProfile();
0084                                 if(!pro)
0085                                     return;
0086                                 pro->setPlayerName(local->name());
0087                             });
0088                     connect(local, &Player::colorChanged, m_networkCtrl,
0089                             [this, local]()
0090                             {
0091                                 auto pro= m_networkCtrl->currentProfile();
0092                                 if(!pro)
0093                                     return;
0094                                 pro->setPlayerColor(local->getColor());
0095                             });
0096 
0097                     auto updateCharacters= [this, local]()
0098                     {
0099                         auto pro= m_networkCtrl->currentProfile();
0100                         if(!pro)
0101                             return;
0102                         pro->setPlayerColor(local->getColor());
0103 
0104                         auto const& characters= local->children();
0105                         std::vector<connection::CharacterData> data;
0106                         data.reserve(characters.size());
0107 
0108                         std::transform(
0109                             std::begin(characters), std::end(characters), std::back_inserter(data),
0110                             [](const std::unique_ptr<Character>& character)
0111                             {
0112                                 QHash<QString, QVariant> params;
0113                                 params.insert(Core::updater::key_char_property_hp, character->getHealthPointsCurrent());
0114                                 params.insert(Core::updater::key_char_property_maxhp, character->getHealthPointsMax());
0115                                 params.insert(Core::updater::key_char_property_minhp, character->getHealthPointsMin());
0116                                 params.insert(Core::updater::key_char_property_dist, character->getDistancePerTurn());
0117                                 params.insert(Core::updater::key_char_property_state_id, character->stateId());
0118                                 params.insert(Core::updater::key_char_property_life_color, character->getLifeColor());
0119                                 params.insert(Core::updater::key_char_property_init_cmd, character->initCommand());
0120                                 params.insert(Core::updater::key_char_property_has_init, character->hasInitScore());
0121                                 params.insert(Core::updater::key_char_property_init_score,
0122                                               character->getInitiativeScore());
0123                                 return connection::CharacterData({character->uuid(), character->name(),
0124                                                                   character->getColor(), character->avatar(), params});
0125                             });
0126 
0127                         pro->setCharacters(data);
0128                     };
0129 
0130                     connect(local, &Player::characterChanged, m_networkCtrl, updateCharacters);
0131                     connect(local, &Player::characterCountChanged, m_networkCtrl, updateCharacters);
0132                 }
0133                 else
0134                     m_ctrl->clear();
0135             });
0136 }
0137 
0138 void PlayerUpdater::updateNewPlayer(Player* player)
0139 {
0140     if(!m_ctrl->localIsGm() && player != m_ctrl->localPlayer())
0141         return;
0142 
0143     connect(player, &Player::avatarChanged, this,
0144             [this, player]() { sendOffChanges<QByteArray>(player, false, Core::person::avatar); });
0145     connect(player, &Player::nameChanged, this,
0146             [this, player]() { sendOffChanges<QString>(player, false, Core::person::name); });
0147     connect(player, &Player::colorChanged, this,
0148             [this, player]() { sendOffChanges<QColor>(player, false, Core::person::color); });
0149 
0150     auto const& characters= player->children();
0151 
0152     for(auto const& character : characters)
0153     {
0154         auto p= character.get();
0155         connect(p, &Character::avatarChanged, this,
0156                 [this, p]() { sendOffChanges<QByteArray>(p, true, Core::person::avatar); });
0157         connect(p, &Character::nameChanged, this,
0158                 [this, p]() { sendOffChanges<QString>(p, true, Core::person::name); });
0159         connect(p, &Character::colorChanged, this,
0160                 [this, p]() { sendOffChanges<QColor>(p, true, Core::person::color); });
0161         connect(p, &Character::currentHealthPointsChanged, this,
0162                 [this, p]() { sendOffChanges<int>(p, true, Core::person::healthPoints); });
0163         connect(p, &Character::npcChanged, this, [this, p]() { sendOffChanges<bool>(p, true, Core::person::isNpc); });
0164         connect(p, &Character::maxHPChanged, this, [this, p]() { sendOffChanges<int>(p, true, Core::person::maxHP); });
0165         connect(p, &Character::minHPChanged, this, [this, p]() { sendOffChanges<int>(p, true, Core::person::minHP); });
0166         connect(p, &Character::distancePerTurnChanged, this,
0167                 [this, p]() { sendOffChanges<int>(p, true, Core::person::distancePerTurn); });
0168 
0169         connect(p, &Character::initCommandChanged, this,
0170                 [this, p]() { sendOffChanges<QString>(p, true, Core::person::initCommand); });
0171         connect(p, &Character::hasInitScoreChanged, this,
0172                 [this, p]() { sendOffChanges<bool>(p, true, Core::person::hasInitiative); });
0173         connect(p, &Character::initiativeChanged, this,
0174                 [this, p]() { sendOffChanges<int>(p, true, Core::person::initiative); });
0175         connect(p, &Character::stateIdChanged, this,
0176                 [this, p]() { sendOffChanges<QString>(p, true, Core::person::stateId); });
0177         connect(p, &Character::lifeColorChanged, this,
0178                 [this, p]() { sendOffChanges<QColor>(p, true, Core::person::lifeColor); });
0179     }
0180 }
0181 
0182 void PlayerUpdater::playerLeft(Player* player)
0183 {
0184     disconnect(player, 0, this, 0);
0185 }