mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 07:19:41 +00:00
[General] Implement sending and reading of ActorEquipment packets
This commit is contained in:
parent
ec921eefc8
commit
4f273932af
16 changed files with 201 additions and 39 deletions
|
@ -32,6 +32,7 @@ void ActorList::reset()
|
|||
animPlayActors.clear();
|
||||
speechActors.clear();
|
||||
statsDynamicActors.clear();
|
||||
equipmentActors.clear();
|
||||
attackActors.clear();
|
||||
cellChangeActors.clear();
|
||||
guid = mwmp::Main::get().getNetworking()->getLocalPlayer()->guid;
|
||||
|
@ -72,6 +73,11 @@ void ActorList::addStatsDynamicActor(LocalActor localActor)
|
|||
statsDynamicActors.push_back(localActor);
|
||||
}
|
||||
|
||||
void ActorList::addEquipmentActor(LocalActor localActor)
|
||||
{
|
||||
equipmentActors.push_back(localActor);
|
||||
}
|
||||
|
||||
void ActorList::addAttackActor(LocalActor localActor)
|
||||
{
|
||||
attackActors.push_back(localActor);
|
||||
|
@ -132,6 +138,16 @@ void ActorList::sendStatsDynamicActors()
|
|||
}
|
||||
}
|
||||
|
||||
void ActorList::sendEquipmentActors()
|
||||
{
|
||||
if (equipmentActors.size() > 0)
|
||||
{
|
||||
baseActors = equipmentActors;
|
||||
Main::get().getNetworking()->getActorPacket(ID_ACTOR_EQUIPMENT)->setActorList(this);
|
||||
Main::get().getNetworking()->getActorPacket(ID_ACTOR_EQUIPMENT)->Send();
|
||||
}
|
||||
}
|
||||
|
||||
void ActorList::sendAttackActors()
|
||||
{
|
||||
if (attackActors.size() > 0)
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace mwmp
|
|||
void addAnimPlayActor(LocalActor localActor);
|
||||
void addSpeechActor(LocalActor localActor);
|
||||
void addStatsDynamicActor(LocalActor localActor);
|
||||
void addEquipmentActor(LocalActor localActor);
|
||||
void addAttackActor(LocalActor localActor);
|
||||
void addCellChangeActor(LocalActor localActor);
|
||||
|
||||
|
@ -34,6 +35,7 @@ namespace mwmp
|
|||
void sendAnimPlayActors();
|
||||
void sendSpeechActors();
|
||||
void sendStatsDynamicActors();
|
||||
void sendEquipmentActors();
|
||||
void sendAttackActors();
|
||||
void sendCellChangeActors();
|
||||
|
||||
|
@ -49,6 +51,7 @@ namespace mwmp
|
|||
std::vector<BaseActor> animPlayActors;
|
||||
std::vector<BaseActor> speechActors;
|
||||
std::vector<BaseActor> statsDynamicActors;
|
||||
std::vector<BaseActor> equipmentActors;
|
||||
std::vector<BaseActor> attackActors;
|
||||
std::vector<BaseActor> cellChangeActors;
|
||||
};
|
||||
|
|
|
@ -75,6 +75,7 @@ void Cell::updateLocal(bool forceUpdate)
|
|||
actorList->sendAnimPlayActors();
|
||||
actorList->sendSpeechActors();
|
||||
actorList->sendStatsDynamicActors();
|
||||
actorList->sendEquipmentActors();
|
||||
actorList->sendAttackActors();
|
||||
actorList->sendCellChangeActors();
|
||||
}
|
||||
|
@ -196,6 +197,29 @@ void Cell::readStatsDynamic(ActorList& actorList)
|
|||
}
|
||||
}
|
||||
|
||||
void Cell::readEquipment(ActorList& actorList)
|
||||
{
|
||||
initializeDedicatedActors(actorList);
|
||||
|
||||
BaseActor baseActor;
|
||||
|
||||
for (unsigned int i = 0; i < actorList.count; i++)
|
||||
{
|
||||
baseActor = actorList.baseActors.at(i);
|
||||
std::string mapIndex = Main::get().getCellController()->generateMapIndex(baseActor);
|
||||
|
||||
if (dedicatedActors.count(mapIndex) > 0)
|
||||
{
|
||||
DedicatedActor *actor = dedicatedActors[mapIndex];
|
||||
|
||||
for (int slot = 0; slot < 19; ++slot)
|
||||
actor->equipedItems[slot] = baseActor.equipedItems[slot];
|
||||
|
||||
actor->setEquipment();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cell::readSpeech(ActorList& actorList)
|
||||
{
|
||||
BaseActor baseActor;
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace mwmp
|
|||
void readAnimFlags(ActorList& actorList);
|
||||
void readAnimPlay(ActorList& actorList);
|
||||
void readStatsDynamic(ActorList& actorList);
|
||||
void readEquipment(ActorList& actorList);
|
||||
void readSpeech(ActorList& actorList);
|
||||
void readAttack(ActorList& actorList);
|
||||
void readCellChange(ActorList& actorList);
|
||||
|
|
|
@ -136,6 +136,19 @@ void CellController::readStatsDynamic(ActorList& actorList)
|
|||
}
|
||||
}
|
||||
|
||||
void CellController::readEquipment(ActorList& actorList)
|
||||
{
|
||||
std::string mapIndex = actorList.cell.getDescription();
|
||||
|
||||
initializeCell(actorList.cell);
|
||||
|
||||
// If this now exists, send it the data
|
||||
if (cellsInitialized.count(mapIndex) > 0)
|
||||
{
|
||||
cellsInitialized[mapIndex]->readEquipment(actorList);
|
||||
}
|
||||
}
|
||||
|
||||
void CellController::readSpeech(ActorList& actorList)
|
||||
{
|
||||
std::string mapIndex = actorList.cell.getDescription();
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace mwmp
|
|||
void readAnimFlags(mwmp::ActorList& actorList);
|
||||
void readAnimPlay(mwmp::ActorList& actorList);
|
||||
void readStatsDynamic(mwmp::ActorList& actorList);
|
||||
void readEquipment(mwmp::ActorList& actorList);
|
||||
void readSpeech(mwmp::ActorList& actorList);
|
||||
void readAttack(mwmp::ActorList& actorList);
|
||||
void readCellChange(mwmp::ActorList& actorList);
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
|
||||
#include "../mwrender/animation.hpp"
|
||||
|
||||
#include "../mwworld/action.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/worldimp.hpp"
|
||||
|
||||
#include "DedicatedActor.hpp"
|
||||
|
@ -127,6 +129,68 @@ void DedicatedActor::setAnimFlags()
|
|||
ptrCreatureStats->setMovementFlag(CreatureStats::Flag_ForceMoveJump, (movementFlags & CreatureStats::Flag_ForceMoveJump) != 0);
|
||||
}
|
||||
|
||||
void DedicatedActor::setStatsDynamic()
|
||||
{
|
||||
// Only set dynamic stats if we have received at least one packet about them
|
||||
if (!hasStatsDynamicData) return;
|
||||
|
||||
MWMechanics::CreatureStats *ptrCreatureStats = &ptr.getClass().getCreatureStats(ptr);
|
||||
MWMechanics::DynamicStat<float> value;
|
||||
|
||||
// Resurrect this Actor if it's not supposed to be dead according to its authority
|
||||
if (creatureStats.mDynamic[0].mCurrent > 0)
|
||||
ptrCreatureStats->resurrect();
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
value.readState(creatureStats.mDynamic[i]);
|
||||
ptrCreatureStats->setDynamic(i, value);
|
||||
}
|
||||
}
|
||||
|
||||
void DedicatedActor::setEquipment()
|
||||
{
|
||||
if (!ptr.getClass().hasInventoryStore(ptr))
|
||||
return;
|
||||
|
||||
MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr);
|
||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
|
||||
const string &dedicItem = equipedItems[slot].refId;
|
||||
std::string item = "";
|
||||
bool equal = false;
|
||||
if (it != invStore.end())
|
||||
{
|
||||
item = it->getCellRef().getRefId();
|
||||
if (!Misc::StringUtils::ciEqual(item, dedicItem)) // if other item equiped
|
||||
{
|
||||
MWWorld::ContainerStore &store = ptr.getClass().getContainerStore(ptr);
|
||||
store.remove(item, store.count(item), ptr);
|
||||
}
|
||||
else
|
||||
equal = true;
|
||||
}
|
||||
|
||||
if (dedicItem.empty() || equal)
|
||||
continue;
|
||||
|
||||
int count = equipedItems[slot].count;
|
||||
ptr.getClass().getContainerStore(ptr).add(dedicItem, count, ptr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it2 = invStore.begin(); it2 != invStore.end(); ++it2)
|
||||
{
|
||||
if (::Misc::StringUtils::ciEqual(it2->getCellRef().getRefId(), dedicItem)) // equip item
|
||||
{
|
||||
boost::shared_ptr<MWWorld::Action> action = it2->getClass().use(*it2);
|
||||
action->execute(ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DedicatedActor::playAnimation()
|
||||
{
|
||||
if (!animation.groupname.empty())
|
||||
|
@ -152,25 +216,6 @@ void DedicatedActor::playSound()
|
|||
}
|
||||
}
|
||||
|
||||
void DedicatedActor::setStatsDynamic()
|
||||
{
|
||||
// Only set dynamic stats if we have received at least one packet about them
|
||||
if (!hasStatsDynamicData) return;
|
||||
|
||||
MWMechanics::CreatureStats *ptrCreatureStats = &ptr.getClass().getCreatureStats(ptr);
|
||||
MWMechanics::DynamicStat<float> value;
|
||||
|
||||
// Resurrect this Actor if it's not supposed to be dead according to its authority
|
||||
if (creatureStats.mDynamic[0].mCurrent > 0)
|
||||
ptrCreatureStats->resurrect();
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
value.readState(creatureStats.mDynamic[i]);
|
||||
ptrCreatureStats->setDynamic(i, value);
|
||||
}
|
||||
}
|
||||
|
||||
MWWorld::Ptr DedicatedActor::getPtr()
|
||||
{
|
||||
return ptr;
|
||||
|
|
|
@ -20,9 +20,10 @@ namespace mwmp
|
|||
void setMovementSettings();
|
||||
void setPosition();
|
||||
void setAnimFlags();
|
||||
void setStatsDynamic();
|
||||
void setEquipment();
|
||||
void playAnimation();
|
||||
void playSound();
|
||||
void setStatsDynamic();
|
||||
|
||||
MWWorld::Ptr getPtr();
|
||||
void setPtr(const MWWorld::Ptr& newPtr);
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
#include "../mwmechanics/mechanicsmanagerimp.hpp"
|
||||
#include "../mwmechanics/movement.hpp"
|
||||
|
||||
#include "../mwrender/animation.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/worldimp.hpp"
|
||||
|
||||
#include "LocalActor.hpp"
|
||||
|
@ -21,6 +23,7 @@ using namespace std;
|
|||
LocalActor::LocalActor()
|
||||
{
|
||||
posWasChanged = false;
|
||||
equipmentChanged = false;
|
||||
|
||||
wasRunning = false;
|
||||
wasSneaking = false;
|
||||
|
@ -45,6 +48,7 @@ LocalActor::~LocalActor()
|
|||
void LocalActor::update(bool forceUpdate)
|
||||
{
|
||||
updateStatsDynamic(forceUpdate);
|
||||
updateEquipment(forceUpdate);
|
||||
|
||||
if (forceUpdate || !creatureStats.mDead)
|
||||
{
|
||||
|
@ -198,6 +202,49 @@ void LocalActor::updateStatsDynamic(bool forceUpdate)
|
|||
}
|
||||
}
|
||||
|
||||
void LocalActor::updateEquipment(bool forceUpdate)
|
||||
{
|
||||
if (!ptr.getClass().hasInventoryStore(ptr))
|
||||
return;
|
||||
|
||||
if (forceUpdate)
|
||||
equipmentChanged = true;
|
||||
|
||||
MWWorld::InventoryStore &invStore = ptr.getClass().getInventoryStore(ptr);
|
||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; slot++)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
if (it != invStore.end() && !::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), equipedItems[slot].refId))
|
||||
{
|
||||
equipmentChanged = true;
|
||||
|
||||
equipedItems[slot].refId = it->getCellRef().getRefId();
|
||||
equipedItems[slot].charge = it->getCellRef().getCharge();
|
||||
if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
|
||||
{
|
||||
MWMechanics::WeaponType weaptype;
|
||||
MWMechanics::getActiveWeapon(ptr.getClass().getCreatureStats(ptr), ptr.getClass().getInventoryStore(ptr), &weaptype);
|
||||
if (weaptype != MWMechanics::WeapType_Thrown)
|
||||
equipedItems[slot].count = 1;
|
||||
}
|
||||
else
|
||||
equipedItems[slot].count = invStore.count(it->getCellRef().getRefId());
|
||||
}
|
||||
else if (it == invStore.end() && !equipedItems[slot].refId.empty())
|
||||
{
|
||||
equipmentChanged = true;
|
||||
equipedItems[slot].refId = "";
|
||||
equipedItems[slot].count = 0;
|
||||
equipedItems[slot].charge = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (equipmentChanged)
|
||||
{
|
||||
mwmp::Main::get().getNetworking()->getActorList()->addEquipmentActor(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalActor::updateAttack()
|
||||
{
|
||||
if (attack.shouldSend)
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace mwmp
|
|||
void updateAnimPlay();
|
||||
void updateSpeech();
|
||||
void updateStatsDynamic(bool forceUpdate);
|
||||
void updateEquipment(bool forceUpdate);
|
||||
void updateAttack();
|
||||
|
||||
MWWorld::Ptr getPtr();
|
||||
|
@ -31,6 +32,7 @@ namespace mwmp
|
|||
MWWorld::Ptr ptr;
|
||||
|
||||
bool posWasChanged;
|
||||
bool equipmentChanged;
|
||||
|
||||
bool wasRunning;
|
||||
bool wasSneaking;
|
||||
|
|
|
@ -409,10 +409,10 @@ void LocalPlayer::updateEquipment(bool forceUpdate)
|
|||
{
|
||||
MWWorld::Ptr player = getPlayerPtr();
|
||||
|
||||
static bool equipChanged = false;
|
||||
static bool equipmentChanged = false;
|
||||
|
||||
if (forceUpdate)
|
||||
equipChanged = true;
|
||||
equipmentChanged = true;
|
||||
|
||||
MWWorld::InventoryStore &invStore = player.getClass().getInventoryStore(player);
|
||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; slot++)
|
||||
|
@ -420,7 +420,7 @@ void LocalPlayer::updateEquipment(bool forceUpdate)
|
|||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
if (it != invStore.end() && !::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), equipedItems[slot].refId))
|
||||
{
|
||||
equipChanged = true;
|
||||
equipmentChanged = true;
|
||||
|
||||
equipedItems[slot].refId = it->getCellRef().getRefId();
|
||||
equipedItems[slot].charge = it->getCellRef().getCharge();
|
||||
|
@ -436,18 +436,18 @@ void LocalPlayer::updateEquipment(bool forceUpdate)
|
|||
}
|
||||
else if (it == invStore.end() && !equipedItems[slot].refId.empty())
|
||||
{
|
||||
equipChanged = true;
|
||||
equipmentChanged = true;
|
||||
equipedItems[slot].refId = "";
|
||||
equipedItems[slot].count = 0;
|
||||
equipedItems[slot].charge = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (equipChanged)
|
||||
if (equipmentChanged)
|
||||
{
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_EQUIPMENT)->setPlayer(this);
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_EQUIPMENT)->Send();
|
||||
equipChanged = false;
|
||||
equipmentChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace mwmp
|
|||
|
||||
virtual void Do(ActorPacket &packet, ActorList &actorList)
|
||||
{
|
||||
|
||||
Main::get().getCellController()->readEquipment(actorList);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ namespace mwmp
|
|||
|
||||
bool hasPositionData;
|
||||
bool hasStatsDynamicData;
|
||||
|
||||
Item equipedItems[19];
|
||||
};
|
||||
|
||||
class BaseActorList
|
||||
|
|
|
@ -26,18 +26,6 @@ namespace mwmp
|
|||
bool loot;
|
||||
};
|
||||
|
||||
struct Item
|
||||
{
|
||||
std::string refId;
|
||||
int count;
|
||||
int charge;
|
||||
|
||||
inline bool operator==(const Item& rhs)
|
||||
{
|
||||
return refId == rhs.refId && count == rhs.count && charge == rhs.charge;
|
||||
}
|
||||
};
|
||||
|
||||
struct JournalItem
|
||||
{
|
||||
std::string quest;
|
||||
|
|
|
@ -7,6 +7,18 @@
|
|||
|
||||
namespace mwmp
|
||||
{
|
||||
struct Item
|
||||
{
|
||||
std::string refId;
|
||||
int count;
|
||||
int charge;
|
||||
|
||||
inline bool operator==(const Item& rhs)
|
||||
{
|
||||
return refId == rhs.refId && count == rhs.count && charge == rhs.charge;
|
||||
}
|
||||
};
|
||||
|
||||
struct Target
|
||||
{
|
||||
std::string refId;
|
||||
|
|
|
@ -38,6 +38,13 @@ void PacketActorEquipment::Packet(RakNet::BitStream *bs, bool send)
|
|||
RW(actor.refNumIndex, send);
|
||||
RW(actor.mpNum, send);
|
||||
|
||||
for (int i = 0; i < 19; i++)
|
||||
{
|
||||
RW(actor.equipedItems[i].refId, send);
|
||||
RW(actor.equipedItems[i].count, send);
|
||||
RW(actor.equipedItems[i].charge, send);
|
||||
}
|
||||
|
||||
if (!send)
|
||||
{
|
||||
actorList->baseActors.push_back(actor);
|
||||
|
|
Loading…
Reference in a new issue