[General] Implement sending and reading of ActorEquipment packets

pull/249/merge
David Cernat 8 years ago
parent ec921eefc8
commit 4f273932af

@ -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…
Cancel
Save