[General] Implement PlayerTeam packet

pull/556/head
David Cernat 5 years ago
parent 385ef55848
commit 753e310dd4

@ -11,6 +11,14 @@ using namespace std;
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
{
Player *player;
@ -181,6 +189,17 @@ void MechanicsFunctions::SetSelectedSpellId(unsigned short pid, const char *spel
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)
{
Player *player;
@ -207,6 +226,19 @@ void MechanicsFunctions::SendSelectedSpell(unsigned short pid)
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,
const char* jailProgressText, const char* jailEndText) noexcept
{

@ -4,7 +4,9 @@
#include "../Types.hpp"
#define MECHANICSAPI \
{"GetMiscellaneousChangeType", MechanicsFunctions::GetMiscellaneousChangeType},\
{"ClearTeamMembersForPlayer", MechanicsFunctions::ClearTeamMembersForPlayer},\
\
{"GetMiscellaneousChangeType", MechanicsFunctions::GetMiscellaneousChangeType},\
\
{"GetMarkCell", MechanicsFunctions::GetMarkCell},\
{"GetMarkPosX", MechanicsFunctions::GetMarkPosX},\
@ -29,8 +31,11 @@
{"SetMarkRot", MechanicsFunctions::SetMarkRot},\
{"SetSelectedSpellId", MechanicsFunctions::SetSelectedSpellId},\
\
{"AddTeamMemberForPlayer", MechanicsFunctions::AddTeamMemberForPlayer},\
\
{"SendMarkLocation", MechanicsFunctions::SendMarkLocation},\
{"SendSelectedSpell", MechanicsFunctions::SendSelectedSpell},\
{"SendTeam", MechanicsFunctions::SendTeam},\
\
{"Jail", MechanicsFunctions::Jail},\
{"Resurrect", MechanicsFunctions::Resurrect},\
@ -42,6 +47,15 @@ class MechanicsFunctions
{
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.
*
@ -225,6 +239,15 @@ public:
*/
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.
*
@ -241,6 +264,16 @@ public:
*/
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.
*

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

@ -14,10 +14,12 @@
Include additional headers for multiplayer purposes
*/
#include <components/openmw-mp/TimedLog.hpp>
#include <components/openmw-mp/Utils.hpp>
#include "../mwmp/Main.hpp"
#include "../mwmp/Networking.hpp"
#include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/PlayerList.hpp"
#include "../mwmp/DedicatedPlayer.hpp"
#include "../mwmp/CellController.hpp"
#include "../mwmp/MechanicsHelper.hpp"
#include "../mwmp/ObjectList.hpp"
@ -2368,6 +2370,23 @@ namespace MWMechanics
if (stats.isDead())
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
// Actors that are targeted by this actor's Follow or Escort packages also side with them
for (const AiPackage* package : stats.getAiSequence())

@ -12,6 +12,7 @@
Include additional headers for multiplayer purposes
*/
#include <components/openmw-mp/TimedLog.hpp>
#include "../mwmp/Main.hpp"
#include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/PlayerList.hpp"
@ -1577,15 +1578,49 @@ namespace MWMechanics
return false;
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;
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();
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");
return false;

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

@ -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

@ -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

@ -3,6 +3,7 @@
#include "../PlayerProcessor.hpp"
#include <components/openmw-mp/Utils.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include "apps/openmw/mwstate/statemanagerimp.hpp"
@ -22,7 +23,23 @@ namespace mwmp
if (isLocal())
MWBase::Environment::get().getStateManager()->requestQuit();
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);
}
}
};
}

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

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

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

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

@ -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
}

@ -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);
}
}

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