diff --git a/apps/openmw/mwmp/ActorList.cpp b/apps/openmw/mwmp/ActorList.cpp index 6a848c7c5..3c90d0e91 100644 --- a/apps/openmw/mwmp/ActorList.cpp +++ b/apps/openmw/mwmp/ActorList.cpp @@ -30,6 +30,7 @@ void ActorList::reset() positionActors.clear(); animFlagsActors.clear(); animPlayActors.clear(); + statsDynamicActors.clear(); guid = mwmp::Main::get().getNetworking()->getLocalPlayer()->guid; } @@ -58,6 +59,11 @@ void ActorList::addAnimPlayActor(LocalActor localActor) animPlayActors.push_back(localActor); } +void ActorList::addStatsDynamicActor(LocalActor localActor) +{ + statsDynamicActors.push_back(localActor); +} + void ActorList::sendPositionActors() { if (positionActors.size() > 0) @@ -88,6 +94,16 @@ void ActorList::sendAnimPlayActors() } } +void ActorList::sendStatsDynamicActors() +{ + if (statsDynamicActors.size() > 0) + { + baseActors = statsDynamicActors; + Main::get().getNetworking()->getActorPacket(ID_ACTOR_STATS_DYNAMIC)->setActorList(this); + Main::get().getNetworking()->getActorPacket(ID_ACTOR_STATS_DYNAMIC)->Send(); + } +} + // TODO: Finish this void ActorList::editActorsInCell(MWWorld::CellStore* cellStore) { diff --git a/apps/openmw/mwmp/ActorList.hpp b/apps/openmw/mwmp/ActorList.hpp index 7a73b2aeb..90dbf0a70 100644 --- a/apps/openmw/mwmp/ActorList.hpp +++ b/apps/openmw/mwmp/ActorList.hpp @@ -24,10 +24,12 @@ namespace mwmp void addPositionActor(LocalActor localActor); void addAnimFlagsActor(LocalActor localActor); void addAnimPlayActor(LocalActor localActor); + void addStatsDynamicActor(LocalActor localActor); void sendPositionActors(); void sendAnimFlagsActors(); void sendAnimPlayActors(); + void sendStatsDynamicActors(); void editActorsInCell(MWWorld::CellStore* cellStore); @@ -39,6 +41,7 @@ namespace mwmp std::vector positionActors; std::vector animFlagsActors; std::vector animPlayActors; + std::vector statsDynamicActors; }; } diff --git a/apps/openmw/mwmp/Cell.cpp b/apps/openmw/mwmp/Cell.cpp index 47ef40d19..610061f47 100644 --- a/apps/openmw/mwmp/Cell.cpp +++ b/apps/openmw/mwmp/Cell.cpp @@ -56,6 +56,7 @@ void Cell::updateLocal(bool forceUpdate) actorList->sendPositionActors(); actorList->sendAnimFlagsActors(); actorList->sendAnimPlayActors(); + actorList->sendStatsDynamicActors(); } void Cell::updateDedicated(float dt) @@ -133,6 +134,25 @@ void Cell::readAnimPlay(ActorList& actorList) } } +void Cell::readStatsDynamic(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]; + actor->creatureStats = baseActor.creatureStats; + } + } +} + void Cell::initializeLocalActors() { ESM::Cell esmCell = *store->getCell(); diff --git a/apps/openmw/mwmp/Cell.hpp b/apps/openmw/mwmp/Cell.hpp index 64138d36f..7b8481834 100644 --- a/apps/openmw/mwmp/Cell.hpp +++ b/apps/openmw/mwmp/Cell.hpp @@ -21,6 +21,7 @@ namespace mwmp void readPositions(ActorList& actorList); void readAnimFlags(ActorList& actorList); void readAnimPlay(ActorList& actorList); + void readStatsDynamic(ActorList& actorList); void initializeLocalActors(); void initializeDedicatedActors(ActorList& actorList); diff --git a/apps/openmw/mwmp/CellController.cpp b/apps/openmw/mwmp/CellController.cpp index 66ac4541e..70ab67026 100644 --- a/apps/openmw/mwmp/CellController.cpp +++ b/apps/openmw/mwmp/CellController.cpp @@ -128,6 +128,19 @@ void CellController::readAnimPlay(ActorList& actorList) } } +void CellController::readStatsDynamic(ActorList& actorList) +{ + std::string mapIndex = actorList.cell.getDescription(); + + initializeCell(actorList.cell); + + // If this now exists, send it the data + if (cellsActive.count(mapIndex) > 0) + { + cellsActive[mapIndex]->readStatsDynamic(actorList); + } +} + void CellController::setLocalActorRecord(std::string actorIndex, std::string cellIndex) { localActorsToCells[actorIndex] = cellIndex; diff --git a/apps/openmw/mwmp/CellController.hpp b/apps/openmw/mwmp/CellController.hpp index 6034cf63b..eb1cb664d 100644 --- a/apps/openmw/mwmp/CellController.hpp +++ b/apps/openmw/mwmp/CellController.hpp @@ -25,6 +25,7 @@ namespace mwmp void readPositions(mwmp::ActorList& actorList); void readAnimFlags(mwmp::ActorList& actorList); void readAnimPlay(mwmp::ActorList& actorList); + void readStatsDynamic(mwmp::ActorList& actorList); void setLocalActorRecord(std::string actorIndex, std::string cellIndex); void removeLocalActorRecord(std::string actorIndex); diff --git a/apps/openmw/mwmp/DedicatedActor.cpp b/apps/openmw/mwmp/DedicatedActor.cpp index 5604900a0..aa32be63e 100644 --- a/apps/openmw/mwmp/DedicatedActor.cpp +++ b/apps/openmw/mwmp/DedicatedActor.cpp @@ -18,6 +18,10 @@ DedicatedActor::DedicatedActor() drawState = 0; movementFlags = 0; animation.groupname = ""; + + creatureStats = new ESM::CreatureStats(); + creatureStats->blank(); + creatureStats->mDynamic[0].mBase = -1; } DedicatedActor::~DedicatedActor() @@ -28,8 +32,9 @@ DedicatedActor::~DedicatedActor() void DedicatedActor::update(float dt) { move(dt); - setDrawState(); - setAnimation(); + setAnimFlags(); + playAnimation(); + setStatsDynamic(); } void DedicatedActor::move(float dt) @@ -46,7 +51,7 @@ void DedicatedActor::move(float dt) world->rotateObject(ptr, position.rot[0], position.rot[1], position.rot[2]); } -void DedicatedActor::setDrawState() +void DedicatedActor::setAnimFlags() { using namespace MWMechanics; @@ -64,7 +69,7 @@ void DedicatedActor::setDrawState() ptrNpcStats->setMovementFlag(CreatureStats::Flag_ForceMoveJump, (movementFlags & CreatureStats::Flag_ForceMoveJump) != 0); } -void DedicatedActor::setAnimation() +void DedicatedActor::playAnimation() { if (!animation.groupname.empty()) { @@ -75,6 +80,21 @@ void DedicatedActor::setAnimation() } } +void DedicatedActor::setStatsDynamic() +{ + // Only set dynamic stats if they have valid values + if (creatureStats->mDynamic[0].mBase == -1) return; + + MWMechanics::NpcStats *ptrNpcStats = &ptr.getClass().getNpcStats(ptr); + MWMechanics::DynamicStat value; + + for (int i = 0; i < 3; ++i) + { + value.readState(creatureStats->mDynamic[i]); + ptrNpcStats->setDynamic(i, value); + } +} + MWWorld::Ptr DedicatedActor::getPtr() { return ptr; diff --git a/apps/openmw/mwmp/DedicatedActor.hpp b/apps/openmw/mwmp/DedicatedActor.hpp index d7d3d4dbd..15c4cbb62 100644 --- a/apps/openmw/mwmp/DedicatedActor.hpp +++ b/apps/openmw/mwmp/DedicatedActor.hpp @@ -16,8 +16,9 @@ namespace mwmp void update(float dt); void move(float dt); - void setDrawState(); - void setAnimation(); + void setAnimFlags(); + void playAnimation(); + void setStatsDynamic(); MWWorld::Ptr getPtr(); void setPtr(const MWWorld::Ptr& newPtr); diff --git a/apps/openmw/mwmp/LocalActor.cpp b/apps/openmw/mwmp/LocalActor.cpp index 27ac13c84..6db117b38 100644 --- a/apps/openmw/mwmp/LocalActor.cpp +++ b/apps/openmw/mwmp/LocalActor.cpp @@ -1,8 +1,12 @@ #include #include "../mwbase/environment.hpp" + +#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/movement.hpp" + #include "../mwrender/animation.hpp" + #include "../mwworld/class.hpp" #include "../mwworld/worldimp.hpp" @@ -25,6 +29,10 @@ LocalActor::LocalActor() wasJumping = false; wasFlying = false; + + statTimer = 0; + + creatureStats = new ESM::CreatureStats(); } LocalActor::~LocalActor() @@ -37,6 +45,7 @@ void LocalActor::update(bool forceUpdate) updatePosition(forceUpdate); updateAnimFlags(forceUpdate); updateAnimPlay(); + updateStatsDynamic(forceUpdate); } void LocalActor::updatePosition(bool forceUpdate) @@ -121,6 +130,34 @@ void LocalActor::updateAnimPlay() } } +void LocalActor::updateStatsDynamic(bool forceUpdate) +{ + MWMechanics::CreatureStats *ptrCreatureStats = &ptr.getClass().getCreatureStats(ptr); + MWMechanics::DynamicStat health(ptrCreatureStats->getHealth()); + MWMechanics::DynamicStat magicka(ptrCreatureStats->getMagicka()); + MWMechanics::DynamicStat fatigue(ptrCreatureStats->getFatigue()); + + const float timeoutSec = 0.5; + + if ((statTimer += MWBase::Environment::get().getFrameDuration()) >= timeoutSec || forceUpdate) + { + if (oldHealth != health || oldMagicka != magicka || oldFatigue != fatigue || forceUpdate) + { + oldHealth = health; + oldMagicka = magicka; + oldFatigue = fatigue; + + health.writeState(creatureStats->mDynamic[0]); + magicka.writeState(creatureStats->mDynamic[1]); + fatigue.writeState(creatureStats->mDynamic[2]); + + statTimer = 0; + + mwmp::Main::get().getNetworking()->getActorList()->addStatsDynamicActor(*this); + } + } +} + MWWorld::Ptr LocalActor::getPtr() { return ptr; @@ -135,4 +172,7 @@ void LocalActor::setPtr(const MWWorld::Ptr& newPtr) mpNum = ptr.getCellRef().getMpNum(); lastDrawState = ptr.getClass().getNpcStats(ptr).getDrawState(); + oldHealth = *(&ptr.getClass().getCreatureStats(ptr).getHealth()); + oldMagicka = *(&ptr.getClass().getCreatureStats(ptr).getMagicka()); + oldFatigue = *(&ptr.getClass().getCreatureStats(ptr).getFatigue()); } diff --git a/apps/openmw/mwmp/LocalActor.hpp b/apps/openmw/mwmp/LocalActor.hpp index 198e408d7..821150b97 100644 --- a/apps/openmw/mwmp/LocalActor.hpp +++ b/apps/openmw/mwmp/LocalActor.hpp @@ -19,6 +19,7 @@ namespace mwmp void updatePosition(bool forceUpdate); void updateAnimFlags(bool forceUpdate); void updateAnimPlay(); + void updateStatsDynamic(bool forceUpdate); MWWorld::Ptr getPtr(); void setPtr(const MWWorld::Ptr& newPtr); @@ -37,6 +38,11 @@ namespace mwmp bool wasFlying; MWMechanics::DrawState_ lastDrawState; + + MWMechanics::DynamicStat oldHealth; + MWMechanics::DynamicStat oldMagicka; + MWMechanics::DynamicStat oldFatigue; + float statTimer; }; } diff --git a/apps/openmw/mwmp/Networking.cpp b/apps/openmw/mwmp/Networking.cpp index cf26d6cde..1b451e3fe 100644 --- a/apps/openmw/mwmp/Networking.cpp +++ b/apps/openmw/mwmp/Networking.cpp @@ -862,6 +862,7 @@ void Networking::processActorPacket(RakNet::Packet *packet) LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Received ID_ACTOR_AUTHORITY about %s", actorList.cell.getDescription().c_str()); Main::get().getCellController()->initializeLocalActors(actorList.cell); + Main::get().getCellController()->getCell(actorList.cell)->updateLocal(true); break; } @@ -883,6 +884,12 @@ void Networking::processActorPacket(RakNet::Packet *packet) break; } + case ID_ACTOR_STATS_DYNAMIC: + { + //Main::get().getCellController()->readStatsDynamic(actorList); + + break; + } case ID_ACTOR_ATTACK: { break; @@ -891,10 +898,6 @@ void Networking::processActorPacket(RakNet::Packet *packet) { break; } - case ID_ACTOR_STATS_DYNAMIC: - { - break; - } case ID_ACTOR_SPEECH: { break; diff --git a/components/openmw-mp/Base/BaseActor.hpp b/components/openmw-mp/Base/BaseActor.hpp index e92fcce47..404c9a115 100644 --- a/components/openmw-mp/Base/BaseActor.hpp +++ b/components/openmw-mp/Base/BaseActor.hpp @@ -2,7 +2,10 @@ #define OPENMW_BASEACTOR_HPP #include +#include + #include + #include namespace mwmp @@ -22,9 +25,11 @@ namespace mwmp ESM::Position position; ESM::Position direction; - + ESM::Cell cell; + ESM::CreatureStats *creatureStats; + unsigned int movementFlags; char drawState; bool isFlying; @@ -52,6 +57,7 @@ namespace mwmp RakNet::RakNetGUID guid; std::vector baseActors; + unsigned int count; ESM::Cell cell; diff --git a/components/openmw-mp/Packets/Actor/PacketActorStatsDynamic.cpp b/components/openmw-mp/Packets/Actor/PacketActorStatsDynamic.cpp index aaedd198b..a4e6e0636 100644 --- a/components/openmw-mp/Packets/Actor/PacketActorStatsDynamic.cpp +++ b/components/openmw-mp/Packets/Actor/PacketActorStatsDynamic.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "PacketActorStatsDynamic.hpp" using namespace mwmp; @@ -33,12 +34,18 @@ void PacketActorStatsDynamic::Packet(RakNet::BitStream *bs, bool send) { actor = actorList->baseActors.at(i); } + else + { + actor.creatureStats = new ESM::CreatureStats(); + } RW(actor.refId, send); RW(actor.refNumIndex, send); RW(actor.mpNum, send); - // TODO: Fill this in + RW(actor.creatureStats->mDynamic[0], send); // health + RW(actor.creatureStats->mDynamic[1], send); // magic + RW(actor.creatureStats->mDynamic[2], send); // fatigue if (!send) {