1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-21 10:53:51 +00:00

[General] Implement PlayerTeam packet

This commit is contained in:
David Cernat 2019-12-02 19:08:03 +02:00
parent 385ef55848
commit 753e310dd4
16 changed files with 225 additions and 57 deletions

View file

@ -11,6 +11,14 @@ using namespace std;
static std::string tempCellDescription; static std::string tempCellDescription;
void MechanicsFunctions::ClearTeamMembersForPlayer(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
player->teamMembers.clear();
}
unsigned char MechanicsFunctions::GetMiscellaneousChangeType(unsigned short pid) noexcept unsigned char MechanicsFunctions::GetMiscellaneousChangeType(unsigned short pid) noexcept
{ {
Player *player; Player *player;
@ -181,6 +189,17 @@ void MechanicsFunctions::SetSelectedSpellId(unsigned short pid, const char *spel
player->selectedSpellId = spellId; player->selectedSpellId = spellId;
} }
void MechanicsFunctions::AddTeamMemberForPlayer(unsigned short pid, unsigned short teamMemberPid) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
Player *teamMember;
GET_PLAYER(teamMemberPid, teamMember, );
player->teamMembers.push_back(teamMember->guid);
}
void MechanicsFunctions::SendMarkLocation(unsigned short pid) void MechanicsFunctions::SendMarkLocation(unsigned short pid)
{ {
Player *player; Player *player;
@ -207,6 +226,19 @@ void MechanicsFunctions::SendSelectedSpell(unsigned short pid)
packet->Send(false); packet->Send(false);
} }
void MechanicsFunctions::SendTeam(unsigned short pid, bool sendToOtherPlayers)
{
Player *player;
GET_PLAYER(pid, player, );
mwmp::PlayerPacket *packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_TEAM);
packet->setPlayer(player);
packet->Send(false);
if (sendToOtherPlayers)
packet->Send(true);
}
void MechanicsFunctions::Jail(unsigned short pid, int jailDays, bool ignoreJailTeleportation, bool ignoreJailSkillIncreases, void MechanicsFunctions::Jail(unsigned short pid, int jailDays, bool ignoreJailTeleportation, bool ignoreJailSkillIncreases,
const char* jailProgressText, const char* jailEndText) noexcept const char* jailProgressText, const char* jailEndText) noexcept
{ {

View file

@ -4,6 +4,8 @@
#include "../Types.hpp" #include "../Types.hpp"
#define MECHANICSAPI \ #define MECHANICSAPI \
{"ClearTeamMembersForPlayer", MechanicsFunctions::ClearTeamMembersForPlayer},\
\
{"GetMiscellaneousChangeType", MechanicsFunctions::GetMiscellaneousChangeType},\ {"GetMiscellaneousChangeType", MechanicsFunctions::GetMiscellaneousChangeType},\
\ \
{"GetMarkCell", MechanicsFunctions::GetMarkCell},\ {"GetMarkCell", MechanicsFunctions::GetMarkCell},\
@ -29,8 +31,11 @@
{"SetMarkRot", MechanicsFunctions::SetMarkRot},\ {"SetMarkRot", MechanicsFunctions::SetMarkRot},\
{"SetSelectedSpellId", MechanicsFunctions::SetSelectedSpellId},\ {"SetSelectedSpellId", MechanicsFunctions::SetSelectedSpellId},\
\ \
{"AddTeamMemberForPlayer", MechanicsFunctions::AddTeamMemberForPlayer},\
\
{"SendMarkLocation", MechanicsFunctions::SendMarkLocation},\ {"SendMarkLocation", MechanicsFunctions::SendMarkLocation},\
{"SendSelectedSpell", MechanicsFunctions::SendSelectedSpell},\ {"SendSelectedSpell", MechanicsFunctions::SendSelectedSpell},\
{"SendTeam", MechanicsFunctions::SendTeam},\
\ \
{"Jail", MechanicsFunctions::Jail},\ {"Jail", MechanicsFunctions::Jail},\
{"Resurrect", MechanicsFunctions::Resurrect},\ {"Resurrect", MechanicsFunctions::Resurrect},\
@ -42,6 +47,15 @@ class MechanicsFunctions
{ {
public: public:
/**
* \brief Clear the list of players who will be regarded as being on this player's
* team.
*
* \param pid The player ID.
* \return void
*/
static void ClearTeamMembersForPlayer(unsigned short pid) noexcept;
/** /**
* \brief Get the type of a PlayerMiscellaneous packet. * \brief Get the type of a PlayerMiscellaneous packet.
* *
@ -225,6 +239,15 @@ public:
*/ */
static void SetSelectedSpellId(unsigned short pid, const char *spellId) noexcept; static void SetSelectedSpellId(unsigned short pid, const char *spellId) noexcept;
/**
* \brief Add a team member to a player's list of team members.
*
* \param pid The player ID.
* \param teamMemberPid The team member's player ID.
* \return void
*/
static void AddTeamMemberForPlayer(unsigned short pid, unsigned short teamMemberPid) noexcept;
/** /**
* \brief Send a PlayerMiscellaneous packet with a Mark location to a player. * \brief Send a PlayerMiscellaneous packet with a Mark location to a player.
* *
@ -241,6 +264,16 @@ public:
*/ */
static void SendSelectedSpell(unsigned short pid); static void SendSelectedSpell(unsigned short pid);
/**
* \brief Send a PlayerTeam packet with a list of team member IDs to a player.
*
* \param pid The player ID.
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
* player attached to the packet (false by default).
* \return void
*/
static void SendTeam(unsigned short pid, bool sendToOtherPlayers);
/** /**
* \brief Send a PlayerJail packet about a player. * \brief Send a PlayerJail packet about a player.
* *

View file

@ -122,7 +122,7 @@ add_openmw_dir (mwmp/processors/player ProcessorChatMessage ProcessorGUIMessageB
ProcessorPlayerInventory ProcessorPlayerItemUse ProcessorPlayerJail ProcessorPlayerJournal ProcessorPlayerLevel ProcessorPlayerInventory ProcessorPlayerItemUse ProcessorPlayerJail ProcessorPlayerJournal ProcessorPlayerLevel
ProcessorPlayerMiscellaneous ProcessorPlayerMomentum ProcessorPlayerPosition ProcessorPlayerQuickKeys ProcessorPlayerReputation ProcessorPlayerMiscellaneous ProcessorPlayerMomentum ProcessorPlayerPosition ProcessorPlayerQuickKeys ProcessorPlayerReputation
ProcessorPlayerResurrect ProcessorPlayerShapeshift ProcessorPlayerSkill ProcessorPlayerSpeech ProcessorPlayerSpellbook ProcessorPlayerResurrect ProcessorPlayerShapeshift ProcessorPlayerSkill ProcessorPlayerSpeech ProcessorPlayerSpellbook
ProcessorPlayerStatsDynamic ProcessorPlayerTopic ProcessorPlayerPlaceholder ProcessorPlayerStatsDynamic ProcessorPlayerTopic ProcessorPlayerTeam
) )
add_openmw_dir (mwmp/processors/object BaseObjectProcessor add_openmw_dir (mwmp/processors/object BaseObjectProcessor

View file

@ -14,10 +14,12 @@
Include additional headers for multiplayer purposes Include additional headers for multiplayer purposes
*/ */
#include <components/openmw-mp/TimedLog.hpp> #include <components/openmw-mp/TimedLog.hpp>
#include <components/openmw-mp/Utils.hpp>
#include "../mwmp/Main.hpp" #include "../mwmp/Main.hpp"
#include "../mwmp/Networking.hpp" #include "../mwmp/Networking.hpp"
#include "../mwmp/LocalPlayer.hpp" #include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/PlayerList.hpp" #include "../mwmp/PlayerList.hpp"
#include "../mwmp/DedicatedPlayer.hpp"
#include "../mwmp/CellController.hpp" #include "../mwmp/CellController.hpp"
#include "../mwmp/MechanicsHelper.hpp" #include "../mwmp/MechanicsHelper.hpp"
#include "../mwmp/ObjectList.hpp" #include "../mwmp/ObjectList.hpp"
@ -2368,6 +2370,23 @@ namespace MWMechanics
if (stats.isDead()) if (stats.isDead())
continue; continue;
/*
Start of tes3mp addition
If we're checking a player and the iteratedActor is another player belonging to this one's teamMembers,
include the iteratedActor in the actors siding with the player
*/
if (actor == getPlayer() && mwmp::PlayerList::isDedicatedPlayer(iteratedActor))
{
if (Utils::vectorContains(mwmp::Main::get().getLocalPlayer()->teamMembers, mwmp::PlayerList::getPlayer(iteratedActor)->guid))
{
list.push_back(iteratedActor);
}
}
/*
End of tes3mp addition
*/
// An actor counts as siding with this actor if Follow or Escort is the current AI package, or there are only Combat and Wander packages before the Follow/Escort package // An actor counts as siding with this actor if Follow or Escort is the current AI package, or there are only Combat and Wander packages before the Follow/Escort package
// Actors that are targeted by this actor's Follow or Escort packages also side with them // Actors that are targeted by this actor's Follow or Escort packages also side with them
for (const AiPackage* package : stats.getAiSequence()) for (const AiPackage* package : stats.getAiSequence())

View file

@ -12,6 +12,7 @@
Include additional headers for multiplayer purposes Include additional headers for multiplayer purposes
*/ */
#include <components/openmw-mp/TimedLog.hpp>
#include "../mwmp/Main.hpp" #include "../mwmp/Main.hpp"
#include "../mwmp/LocalPlayer.hpp" #include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/PlayerList.hpp" #include "../mwmp/PlayerList.hpp"
@ -1577,15 +1578,49 @@ namespace MWMechanics
return false; return false;
MWMechanics::CreatureStats& statsTarget = target.getClass().getCreatureStats(target); MWMechanics::CreatureStats& statsTarget = target.getClass().getCreatureStats(target);
if (attacker == player) /*
Start of tes3mp change (major)
Allow collateral damage from dedicated players as well
*/
if (attacker == player || mwmp::PlayerList::isDedicatedPlayer(attacker))
/*
End of tes3mp change (major)
*/
{ {
std::set<MWWorld::Ptr> followersAttacker; std::set<MWWorld::Ptr> followersAttacker;
getActorsSidingWith(attacker, followersAttacker); getActorsSidingWith(attacker, followersAttacker);
if (followersAttacker.find(target) != followersAttacker.end())
/*
Start of tes3mp change (major)
Check not only whether the target is on the same side as the attacker,
but also whether the attacker is on the same side as the target,
thus allowing for NPC companions of one player to forgive another player
when those players are allied
*/
std::set<MWWorld::Ptr> followersTarget;
getActorsSidingWith(target, followersTarget);
if (followersAttacker.find(target) != followersAttacker.end() || followersTarget.find(attacker) != followersTarget.end())
/*
End of tes3mp change (major)
*/
{ {
statsTarget.friendlyHit(); statsTarget.friendlyHit();
if (statsTarget.getFriendlyHits() < 4) /*
Start of tes3mp change (major)
Due to a greater propensity for collateral damage in multiplayer,
allow more friendly hits
TODO: Allow the server to change the count of the friendly hits
*/
if (statsTarget.getFriendlyHits() < 8)
/*
End of tes3mp change (major)
*/
{ {
MWBase::Environment::get().getDialogueManager()->say(target, "hit"); MWBase::Environment::get().getDialogueManager()->say(target, "hit");
return false; return false;

View file

@ -30,7 +30,6 @@
#include "player/ProcessorPlayerItemUse.hpp" #include "player/ProcessorPlayerItemUse.hpp"
#include "player/ProcessorPlayerJail.hpp" #include "player/ProcessorPlayerJail.hpp"
#include "player/ProcessorPlayerJournal.hpp" #include "player/ProcessorPlayerJournal.hpp"
#include "player/ProcessorPlayerPlaceholder.hpp"
#include "player/ProcessorPlayerLevel.hpp" #include "player/ProcessorPlayerLevel.hpp"
#include "player/ProcessorPlayerMiscellaneous.hpp" #include "player/ProcessorPlayerMiscellaneous.hpp"
#include "player/ProcessorPlayerMomentum.hpp" #include "player/ProcessorPlayerMomentum.hpp"
@ -44,6 +43,7 @@
#include "player/ProcessorPlayerSpeech.hpp" #include "player/ProcessorPlayerSpeech.hpp"
#include "player/ProcessorPlayerSpellbook.hpp" #include "player/ProcessorPlayerSpellbook.hpp"
#include "player/ProcessorPlayerStatsDynamic.hpp" #include "player/ProcessorPlayerStatsDynamic.hpp"
#include "player/ProcessorPlayerTeam.hpp"
#include "player/ProcessorPlayerTopic.hpp" #include "player/ProcessorPlayerTopic.hpp"
#include "ObjectProcessor.hpp" #include "ObjectProcessor.hpp"
@ -133,7 +133,6 @@ void ProcessorInitializer()
PlayerProcessor::AddProcessor(new ProcessorPlayerItemUse()); PlayerProcessor::AddProcessor(new ProcessorPlayerItemUse());
PlayerProcessor::AddProcessor(new ProcessorPlayerJail()); PlayerProcessor::AddProcessor(new ProcessorPlayerJail());
PlayerProcessor::AddProcessor(new ProcessorPlayerJournal()); PlayerProcessor::AddProcessor(new ProcessorPlayerJournal());
PlayerProcessor::AddProcessor(new ProcessorPlayerPlaceholder());
PlayerProcessor::AddProcessor(new ProcessorPlayerLevel()); PlayerProcessor::AddProcessor(new ProcessorPlayerLevel());
PlayerProcessor::AddProcessor(new ProcessorPlayerMiscellaneous()); PlayerProcessor::AddProcessor(new ProcessorPlayerMiscellaneous());
PlayerProcessor::AddProcessor(new ProcessorPlayerMomentum()); PlayerProcessor::AddProcessor(new ProcessorPlayerMomentum());
@ -147,6 +146,7 @@ void ProcessorInitializer()
PlayerProcessor::AddProcessor(new ProcessorPlayerSpeech()); PlayerProcessor::AddProcessor(new ProcessorPlayerSpeech());
PlayerProcessor::AddProcessor(new ProcessorPlayerSpellbook()); PlayerProcessor::AddProcessor(new ProcessorPlayerSpellbook());
PlayerProcessor::AddProcessor(new ProcessorPlayerStatsDynamic()); PlayerProcessor::AddProcessor(new ProcessorPlayerStatsDynamic());
PlayerProcessor::AddProcessor(new ProcessorPlayerTeam());
PlayerProcessor::AddProcessor(new ProcessorPlayerTopic()); PlayerProcessor::AddProcessor(new ProcessorPlayerTopic());
ObjectProcessor::AddProcessor(new ProcessorConsoleCommand()); ObjectProcessor::AddProcessor(new ProcessorConsoleCommand());

View file

@ -1,30 +0,0 @@
#ifndef OPENMW_PROCESSORPLACEHOLDER_HPP
#define OPENMW_PROCESSORPLACEHOLDER_HPP
#include "../PlayerProcessor.hpp"
namespace mwmp
{
class ProcessorPlayerPlaceholder final: public PlayerProcessor
{
public:
ProcessorPlayerPlaceholder()
{
BPP_INIT(ID_PLACEHOLDER)
}
virtual void Do(PlayerPacket &packet, BasePlayer *player)
{
if (isRequest())
{
// Entire list of topics cannot currently be requested from players
}
else if (player != 0)
{
// Placeholder
}
}
};
}
#endif //OPENMW_PROCESSORPLACEHOLDER_HPP

View file

@ -0,0 +1,42 @@
#ifndef OPENMW_PROCESSORPLAYERTEAM_HPP
#define OPENMW_PROCESSORPLAYERTEAM_HPP
#include "../PlayerProcessor.hpp"
#include "apps/openmw/mwmp/Main.hpp"
#include "apps/openmw/mwmp/LocalPlayer.hpp"
namespace mwmp
{
class ProcessorPlayerTeam final: public PlayerProcessor
{
public:
ProcessorPlayerTeam()
{
BPP_INIT(ID_PLAYER_TEAM)
}
virtual void Do(PlayerPacket &packet, BasePlayer *player)
{
if (isLocal())
{
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received ID_PLAYER_TEAM about LocalPlayer from server");
mwmp::LocalPlayer *localPlayer = mwmp::Main::get().getLocalPlayer();
for (std::vector<RakNet::RakNetGUID>::iterator iter = localPlayer->teamMembers.begin(); iter != localPlayer->teamMembers.end(); )
{
DedicatedPlayer *dedicatedPlayer = PlayerList::getPlayer(*iter);
if (dedicatedPlayer)
{
LOG_APPEND(TimedLog::LOG_INFO, "- Adding %s to our team members", dedicatedPlayer->npc.mName.c_str());
}
++iter;
}
}
}
};
}
#endif //OPENMW_PROCESSORPLAYERTEAM_HPP

View file

@ -3,6 +3,7 @@
#include "../PlayerProcessor.hpp" #include "../PlayerProcessor.hpp"
#include <components/openmw-mp/Utils.hpp>
#include <apps/openmw/mwbase/environment.hpp> #include <apps/openmw/mwbase/environment.hpp>
#include "apps/openmw/mwstate/statemanagerimp.hpp" #include "apps/openmw/mwstate/statemanagerimp.hpp"
@ -22,8 +23,24 @@ namespace mwmp
if (isLocal()) if (isLocal())
MWBase::Environment::get().getStateManager()->requestQuit(); MWBase::Environment::get().getStateManager()->requestQuit();
else if (player != 0) else if (player != 0)
{
mwmp::LocalPlayer *localPlayer = mwmp::Main::get().getLocalPlayer();
for (std::vector<RakNet::RakNetGUID>::iterator iter = localPlayer->teamMembers.begin(); iter != localPlayer->teamMembers.end(); )
{
if (*iter == guid)
{
DedicatedPlayer *dedicatedPlayer = PlayerList::getPlayer(guid);
LOG_APPEND(TimedLog::LOG_INFO, "- Deleting %s from our team members", dedicatedPlayer->npc.mName.c_str());
iter = localPlayer->teamMembers.erase(iter);
}
else
++iter;
}
PlayerList::deletePlayer(guid); PlayerList::deletePlayer(guid);
} }
}
}; };
} }

View file

@ -198,7 +198,7 @@ add_component_dir (openmw-mp/Packets/Player
PacketPlayerShapeshift PacketPlayerSkill PacketPlayerSpeech PacketPlayerSpellbook PacketPlayerStatsDynamic PacketPlayerShapeshift PacketPlayerSkill PacketPlayerSpeech PacketPlayerSpellbook PacketPlayerStatsDynamic
PacketPlayerTopic PacketPlayerTopic
PacketPlayerPlaceholder PacketPlayerTeam
) )
add_component_dir (openmw-mp/Packets/Object add_component_dir (openmw-mp/Packets/Object

View file

@ -216,6 +216,7 @@ namespace mwmp
std::vector<CellState> cellStateChanges; std::vector<CellState> cellStateChanges;
ESM::ActiveSpells activeSpells; ESM::ActiveSpells activeSpells;
std::vector<RakNet::RakNetGUID> teamMembers;
CurrentContainer currentContainer; CurrentContainer currentContainer;
int difficulty = 0; int difficulty = 0;

View file

@ -25,7 +25,7 @@
#include "../Packets/Player/PacketPlayerItemUse.hpp" #include "../Packets/Player/PacketPlayerItemUse.hpp"
#include "../Packets/Player/PacketPlayerJail.hpp" #include "../Packets/Player/PacketPlayerJail.hpp"
#include "../Packets/Player/PacketPlayerJournal.hpp" #include "../Packets/Player/PacketPlayerJournal.hpp"
#include "../Packets/Player/PacketPlayerPlaceholder.hpp" #include "../Packets/Player/PacketPlayerTeam.hpp"
#include "../Packets/Player/PacketPlayerLevel.hpp" #include "../Packets/Player/PacketPlayerLevel.hpp"
#include "../Packets/Player/PacketPlayerMiscellaneous.hpp" #include "../Packets/Player/PacketPlayerMiscellaneous.hpp"
#include "../Packets/Player/PacketPlayerMomentum.hpp" #include "../Packets/Player/PacketPlayerMomentum.hpp"
@ -81,7 +81,7 @@ mwmp::PlayerPacketController::PlayerPacketController(RakNet::RakPeerInterface *p
AddPacket<PacketPlayerItemUse>(&packets, peer); AddPacket<PacketPlayerItemUse>(&packets, peer);
AddPacket<PacketPlayerJail>(&packets, peer); AddPacket<PacketPlayerJail>(&packets, peer);
AddPacket<PacketPlayerJournal>(&packets, peer); AddPacket<PacketPlayerJournal>(&packets, peer);
AddPacket<PacketPlayerPlaceholder>(&packets, peer); AddPacket<PacketPlayerTeam>(&packets, peer);
AddPacket<PacketPlayerLevel>(&packets, peer); AddPacket<PacketPlayerLevel>(&packets, peer);
AddPacket<PacketPlayerMiscellaneous>(&packets, peer); AddPacket<PacketPlayerMiscellaneous>(&packets, peer);
AddPacket<PacketPlayerMomentum>(&packets, peer); AddPacket<PacketPlayerMomentum>(&packets, peer);

View file

@ -109,6 +109,7 @@ enum GameMessages
ID_PLAYER_ITEM_USE, ID_PLAYER_ITEM_USE,
ID_PLAYER_CAST, ID_PLAYER_CAST,
ID_PLAYER_TEAM,
ID_PLACEHOLDER ID_PLACEHOLDER
}; };

View file

@ -1,12 +0,0 @@
#include <components/openmw-mp/NetworkMessages.hpp>
#include "PacketPlayerPlaceholder.hpp"
mwmp::PacketPlayerPlaceholder::PacketPlayerPlaceholder(RakNet::RakPeerInterface *peer) : PlayerPacket(peer)
{
packetID = ID_PLACEHOLDER;
}
void mwmp::PacketPlayerPlaceholder::Packet(RakNet::BitStream *bs, bool send)
{
// Placeholder
}

View file

@ -0,0 +1,30 @@
#include <components/openmw-mp/NetworkMessages.hpp>
#include "PacketPlayerTeam.hpp"
mwmp::PacketPlayerTeam::PacketPlayerTeam(RakNet::RakPeerInterface *peer) : PlayerPacket(peer)
{
packetID = ID_PLAYER_TEAM;
}
void mwmp::PacketPlayerTeam::Packet(RakNet::BitStream *bs, bool send)
{
PlayerPacket::Packet(bs, send);
uint32_t count;
if (send)
count = static_cast<uint32_t>(player->teamMembers.size());
RW(count, send);
if (!send)
{
player->teamMembers.clear();
player->teamMembers.resize(count);
}
for (auto &&teamPlayerGuid : player->teamMembers)
{
RW(teamPlayerGuid, send, true);
}
}

View file

@ -1,17 +1,17 @@
#ifndef OPENMW_PACKETPLACEHOLDER_HPP #ifndef OPENMW_PACKETTEAM_HPP
#define OPENMW_PACKETPLACEHOLDER_HPP #define OPENMW_PACKETTEAM_HPP
#include <components/openmw-mp/Packets/Player/PlayerPacket.hpp> #include <components/openmw-mp/Packets/Player/PlayerPacket.hpp>
namespace mwmp namespace mwmp
{ {
class PacketPlayerPlaceholder : public PlayerPacket class PacketPlayerTeam : public PlayerPacket
{ {
public: public:
PacketPlayerPlaceholder(RakNet::RakPeerInterface *peer); PacketPlayerTeam(RakNet::RakPeerInterface *peer);
virtual void Packet(RakNet::BitStream *bs, bool send); virtual void Packet(RakNet::BitStream *bs, bool send);
}; };
} }
#endif //OPENMW_PACKETPLACEHOLDER_HPP #endif //OPENMW_PACKETTEAM_HPP