diff --git a/apps/openmw/mwmp/ActorList.cpp b/apps/openmw/mwmp/ActorList.cpp index 0df6bc334..19764f3ce 100644 --- a/apps/openmw/mwmp/ActorList.cpp +++ b/apps/openmw/mwmp/ActorList.cpp @@ -28,6 +28,7 @@ void ActorList::reset() cell.blank(); baseActors.clear(); positionActors.clear(); + drawStateActors.clear(); guid = mwmp::Main::get().getNetworking()->getLocalPlayer()->guid; } @@ -46,6 +47,11 @@ void ActorList::addPositionActor(LocalActor localActor) positionActors.push_back(localActor); } +void ActorList::addDrawStateActor(LocalActor localActor) +{ + drawStateActors.push_back(localActor); +} + void ActorList::sendPositionActors() { baseActors = positionActors; @@ -53,6 +59,13 @@ void ActorList::sendPositionActors() Main::get().getNetworking()->getActorPacket(ID_ACTOR_POSITION)->Send(); } +void ActorList::sendDrawStateActors() +{ + baseActors = drawStateActors; + Main::get().getNetworking()->getActorPacket(ID_ACTOR_DRAW_STATE)->setActorList(this); + Main::get().getNetworking()->getActorPacket(ID_ACTOR_DRAW_STATE)->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 42981c0db..74d271f84 100644 --- a/apps/openmw/mwmp/ActorList.hpp +++ b/apps/openmw/mwmp/ActorList.hpp @@ -22,8 +22,10 @@ namespace mwmp void addActor(LocalActor localActor); void addPositionActor(LocalActor localActor); + void addDrawStateActor(LocalActor localActor); void sendPositionActors(); + void sendDrawStateActors(); void editActorsInCell(MWWorld::CellStore* cellStore); @@ -33,6 +35,7 @@ namespace mwmp Networking *getNetworking(); std::vector positionActors; + std::vector drawStateActors; }; } diff --git a/apps/openmw/mwmp/Cell.cpp b/apps/openmw/mwmp/Cell.cpp index 4b6d7d99a..fd0cce815 100644 --- a/apps/openmw/mwmp/Cell.cpp +++ b/apps/openmw/mwmp/Cell.cpp @@ -85,6 +85,27 @@ void Cell::readPositions(ActorList& actorList) } } +void Cell::readDrawStates(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->movementFlags = baseActor.movementFlags; + actor->drawState = baseActor.drawState; + actor->isFlying = baseActor.isFlying; + } + } +} + void Cell::initializeLocalActors() { ESM::Cell esmCell = *store->getCell(); diff --git a/apps/openmw/mwmp/Cell.hpp b/apps/openmw/mwmp/Cell.hpp index 438636b94..4b232756c 100644 --- a/apps/openmw/mwmp/Cell.hpp +++ b/apps/openmw/mwmp/Cell.hpp @@ -19,6 +19,7 @@ namespace mwmp void updateDedicated(float dt); void readPositions(ActorList& actorList); + void readDrawStates(ActorList& actorList); void initializeLocalActors(); void initializeDedicatedActors(ActorList& actorList); diff --git a/apps/openmw/mwmp/CellController.cpp b/apps/openmw/mwmp/CellController.cpp index 43a16587a..c25048fee 100644 --- a/apps/openmw/mwmp/CellController.cpp +++ b/apps/openmw/mwmp/CellController.cpp @@ -102,6 +102,19 @@ void CellController::readPositions(ActorList& actorList) } } +void CellController::readDrawStates(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]->readDrawStates(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 f4ee32ece..04c4c0c37 100644 --- a/apps/openmw/mwmp/CellController.hpp +++ b/apps/openmw/mwmp/CellController.hpp @@ -21,7 +21,9 @@ namespace mwmp void initializeCell(const ESM::Cell& cell); void initializeLocalActors(const ESM::Cell& cell); + void readPositions(mwmp::ActorList& actorList); + void readDrawStates(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 3b7024495..017bb3979 100644 --- a/apps/openmw/mwmp/DedicatedActor.cpp +++ b/apps/openmw/mwmp/DedicatedActor.cpp @@ -26,7 +26,7 @@ DedicatedActor::~DedicatedActor() void DedicatedActor::update(float dt) { move(dt); - //setDrawState(); + setDrawState(); //setAnimation(); } @@ -54,6 +54,12 @@ void DedicatedActor::setDrawState() ptr.getClass().getNpcStats(ptr).setDrawState(DrawState_Weapon); else if (drawState == 2) ptr.getClass().getNpcStats(ptr).setDrawState(DrawState_Spell); + + MWMechanics::NpcStats *ptrNpcStats = &ptr.getClass().getNpcStats(ptr); + ptrNpcStats->setMovementFlag(CreatureStats::Flag_Run, (movementFlags & CreatureStats::Flag_Run) != 0); + ptrNpcStats->setMovementFlag(CreatureStats::Flag_Sneak, (movementFlags & CreatureStats::Flag_Sneak) != 0); + ptrNpcStats->setMovementFlag(CreatureStats::Flag_ForceJump, (movementFlags & CreatureStats::Flag_ForceJump) != 0); + ptrNpcStats->setMovementFlag(CreatureStats::Flag_ForceMoveJump, (movementFlags & CreatureStats::Flag_ForceMoveJump) != 0); } void DedicatedActor::setAnimation() @@ -73,4 +79,8 @@ MWWorld::Ptr DedicatedActor::getPtr() void DedicatedActor::setPtr(const MWWorld::Ptr& newPtr) { ptr = newPtr; + + refId = ptr.getCellRef().getRefId(); + refNumIndex = ptr.getCellRef().getRefNum().mIndex; + mpNum = ptr.getCellRef().getMpNum(); } diff --git a/apps/openmw/mwmp/LocalActor.cpp b/apps/openmw/mwmp/LocalActor.cpp index c5c4580f0..14f4b13ff 100644 --- a/apps/openmw/mwmp/LocalActor.cpp +++ b/apps/openmw/mwmp/LocalActor.cpp @@ -2,7 +2,6 @@ #include "../mwbase/environment.hpp" #include "../mwmechanics/movement.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwrender/animation.hpp" #include "../mwworld/class.hpp" #include "../mwworld/worldimp.hpp" @@ -18,6 +17,14 @@ using namespace std; LocalActor::LocalActor() { posWasChanged = false; + + wasRunning = false; + wasSneaking = false; + wasForceJumping = false; + wasForceMoveJumping = false; + + wasJumping = false; + wasFlying = false; } LocalActor::~LocalActor() @@ -28,7 +35,7 @@ LocalActor::~LocalActor() void LocalActor::update(bool forceUpdate) { updatePosition(forceUpdate); - updateDrawState(); + updateDrawStateAndFlags(forceUpdate); } void LocalActor::updatePosition(bool forceUpdate) @@ -42,14 +49,66 @@ void LocalActor::updatePosition(bool forceUpdate) position = ptr.getRefData().getPosition(); - ActorList *actorList = mwmp::Main::get().getNetworking()->getActorList(); - actorList->addPositionActor(*this); + mwmp::Main::get().getNetworking()->getActorList()->addPositionActor(*this); } } -void LocalActor::updateDrawState() +void LocalActor::updateDrawStateAndFlags(bool forceUpdate) { - drawState = ptr.getClass().getNpcStats(ptr).getDrawState(); + MWBase::World *world = MWBase::Environment::get().getWorld(); + MWMechanics::NpcStats ptrNpcStats = ptr.getClass().getNpcStats(ptr); + + using namespace MWMechanics; + + bool isRunning = ptrNpcStats.getMovementFlag(CreatureStats::Flag_Run); + bool isSneaking = ptrNpcStats.getMovementFlag(CreatureStats::Flag_Sneak); + bool isForceJumping = ptrNpcStats.getMovementFlag(CreatureStats::Flag_ForceJump); + bool isForceMoveJumping = ptrNpcStats.getMovementFlag(CreatureStats::Flag_ForceMoveJump); + + isFlying = world->isFlying(ptr); + bool isJumping = ptr.getRefData().isEnabled() && !world->isOnGround(ptr) && !isFlying; + + MWMechanics::DrawState_ currentDrawState = ptr.getClass().getNpcStats(ptr).getDrawState(); + + if (wasRunning != isRunning + || wasSneaking != isSneaking || wasForceJumping != isForceJumping + || wasForceMoveJumping != isForceMoveJumping || lastDrawState != currentDrawState + || wasJumping || isJumping || wasFlying || isFlying + || forceUpdate) + { + wasRunning = isRunning; + wasSneaking = isSneaking; + wasForceJumping = isForceJumping; + wasForceMoveJumping = isForceMoveJumping; + lastDrawState = currentDrawState; + + wasFlying = isFlying; + wasJumping = isJumping; + + movementFlags = 0; + +#define __SETFLAG(flag, value) (value) ? (movementFlags | flag) : (movementFlags & ~flag) + + movementFlags = __SETFLAG(CreatureStats::Flag_Sneak, isSneaking); + movementFlags = __SETFLAG(CreatureStats::Flag_Run, isRunning); + movementFlags = __SETFLAG(CreatureStats::Flag_ForceJump, isForceJumping); + movementFlags = __SETFLAG(CreatureStats::Flag_ForceJump, isJumping); + movementFlags = __SETFLAG(CreatureStats::Flag_ForceMoveJump, isForceMoveJumping); + +#undef __SETFLAG + + if (currentDrawState == MWMechanics::DrawState_Nothing) + drawState = 0; + else if (currentDrawState == MWMechanics::DrawState_Weapon) + drawState = 1; + else if (currentDrawState == MWMechanics::DrawState_Spell) + drawState = 2; + + if (isJumping) + updatePosition(true); // fix position after jump; + + mwmp::Main::get().getNetworking()->getActorList()->addDrawStateActor(*this); + } } MWWorld::Ptr LocalActor::getPtr() @@ -61,7 +120,9 @@ void LocalActor::setPtr(const MWWorld::Ptr& newPtr) { ptr = newPtr; - refId = newPtr.getCellRef().getRefId(); - refNumIndex = newPtr.getCellRef().getRefNum().mIndex; - mpNum = newPtr.getCellRef().getMpNum(); + refId = ptr.getCellRef().getRefId(); + refNumIndex = ptr.getCellRef().getRefNum().mIndex; + mpNum = ptr.getCellRef().getMpNum(); + + lastDrawState = ptr.getClass().getNpcStats(ptr).getDrawState(); } diff --git a/apps/openmw/mwmp/LocalActor.hpp b/apps/openmw/mwmp/LocalActor.hpp index 06ef190ff..b2fb73a38 100644 --- a/apps/openmw/mwmp/LocalActor.hpp +++ b/apps/openmw/mwmp/LocalActor.hpp @@ -2,6 +2,7 @@ #define OPENMW_LOCALACTOR_HPP #include +#include "../mwmechanics/npcstats.hpp" #include "../mwworld/manualref.hpp" namespace mwmp @@ -16,7 +17,7 @@ namespace mwmp void update(bool forceUpdate); void updatePosition(bool forceUpdate); - void updateDrawState(); + void updateDrawStateAndFlags(bool forceUpdate); MWWorld::Ptr getPtr(); void setPtr(const MWWorld::Ptr& newPtr); @@ -25,6 +26,16 @@ namespace mwmp MWWorld::Ptr ptr; bool posWasChanged; + + bool wasRunning; + bool wasSneaking; + bool wasForceJumping; + bool wasForceMoveJumping; + + bool wasJumping; + bool wasFlying; + + MWMechanics::DrawState_ lastDrawState; }; } diff --git a/apps/openmw/mwmp/Networking.cpp b/apps/openmw/mwmp/Networking.cpp index 26131aacf..96f2088ba 100644 --- a/apps/openmw/mwmp/Networking.cpp +++ b/apps/openmw/mwmp/Networking.cpp @@ -861,42 +861,44 @@ 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()->initializeLocalActors(actorList.cell); break; } - case ID_ACTOR_TEST: + case ID_ACTOR_POSITION: { + //Main::get().getCellController()->readPositions(actorList); + break; } - case ID_ACTOR_ANIM_PLAY: + case ID_ACTOR_DRAW_STATE: { + //Main::get().getCellController()->readDrawStates(actorList); + break; } - case ID_ACTOR_ATTACK: + case ID_ACTOR_TEST: { break; } - case ID_ACTOR_CELL_CHANGE: + case ID_ACTOR_ANIM_PLAY: { break; } - case ID_ACTOR_DRAW_STATE: + case ID_ACTOR_ATTACK: { break; } - case ID_ACTOR_DYNAMICSTATS: + case ID_ACTOR_CELL_CHANGE: { break; } - case ID_ACTOR_HEAD_ROTATION: + case ID_ACTOR_DYNAMICSTATS: { break; } - case ID_ACTOR_POSITION: + case ID_ACTOR_HEAD_ROTATION: { - //Main::get().getCellController()->readPositions(actorList); - break; } case ID_ACTOR_SPEECH: diff --git a/components/openmw-mp/Base/BaseActor.hpp b/components/openmw-mp/Base/BaseActor.hpp index 1fbfbe02d..bfd0ffe4e 100644 --- a/components/openmw-mp/Base/BaseActor.hpp +++ b/components/openmw-mp/Base/BaseActor.hpp @@ -25,6 +25,7 @@ namespace mwmp ESM::Cell cell; + unsigned int movementFlags; char drawState; bool isFlying; diff --git a/components/openmw-mp/Packets/Actor/PacketActorDrawState.cpp b/components/openmw-mp/Packets/Actor/PacketActorDrawState.cpp index 8199826ce..620d39b57 100644 --- a/components/openmw-mp/Packets/Actor/PacketActorDrawState.cpp +++ b/components/openmw-mp/Packets/Actor/PacketActorDrawState.cpp @@ -37,8 +37,10 @@ void PacketActorDrawState::Packet(RakNet::BitStream *bs, bool send) RW(actor.refId, send); RW(actor.refNumIndex, send); RW(actor.mpNum, send); - - // TODO: Fill this in + + RW(actor.movementFlags, send); + RW(actor.drawState, send); + RW(actor.isFlying, send); if (!send) { diff --git a/components/openmw-mp/Packets/Actor/PacketActorPosition.cpp b/components/openmw-mp/Packets/Actor/PacketActorPosition.cpp index b308dffe3..a7ef0f3db 100644 --- a/components/openmw-mp/Packets/Actor/PacketActorPosition.cpp +++ b/components/openmw-mp/Packets/Actor/PacketActorPosition.cpp @@ -37,6 +37,7 @@ void PacketActorPosition::Packet(RakNet::BitStream *bs, bool send) RW(actor.refId, send); RW(actor.refNumIndex, send); RW(actor.mpNum, send); + RW(actor.position, send); RW(actor.direction, send);