diff --git a/apps/openmw/mwmp/DedicatedPlayer.cpp b/apps/openmw/mwmp/DedicatedPlayer.cpp index ff3476931..eb856ab74 100644 --- a/apps/openmw/mwmp/DedicatedPlayer.cpp +++ b/apps/openmw/mwmp/DedicatedPlayer.cpp @@ -16,6 +16,7 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/mechanicsmanagerimp.hpp" +#include "../mwmechanics/spellcasting.hpp" #include "../mwworld/action.hpp" #include "../mwworld/cellstore.hpp" @@ -220,12 +221,12 @@ void DedicatedPlayer::move(float dt) ESM::Position refPos = ptr.getRefData().getPosition(); MWBase::World *world = MWBase::Environment::get().getWorld(); - { osg::Vec3f lerp = Lerp(refPos.asVec3(), position.asVec3(), dt * 15); refPos.pos[0] = lerp.x(); refPos.pos[1] = lerp.y(); refPos.pos[2] = lerp.z(); + world->moveObject(ptr, refPos.pos[0], refPos.pos[1], refPos.pos[2]); } @@ -265,7 +266,6 @@ void Players::update(float dt) if (ptrNpcStats->isDead()) ptrNpcStats->resurrect(); - ptrNpcStats->setAttacked(false); ptrNpcStats->getAiSequence().stopCombat(); @@ -429,8 +429,24 @@ DedicatedPlayer *Players::getPlayer(const MWWorld::Ptr &ptr) void DedicatedPlayer::updateDrawState() { - using namespace MWMechanics; + + MWBase::World *world = MWBase::Environment::get().getWorld(); + + // Until we figure out a better workaround for disabling player gravity, + // simply cast Levitate over and over on a player that's supposed to be flying + if (!isFlying) + { + ptr.getClass().getCreatureStats(ptr).getActiveSpells().purgeEffect(ESM::MagicEffect::Levitate); + } + else if (isFlying && !world->isFlying(ptr)) + { + MWMechanics::CastSpell cast(ptr, ptr); + cast.mHitPosition = ptr.getRefData().getPosition().asVec3(); + cast.mAlwaysSucceed = true; + cast.cast("Levitate"); + } + if (drawState == 0) ptr.getClass().getNpcStats(ptr).setDrawState(DrawState_Nothing); else if (drawState == 1) diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index d0c1d8bc8..9846ffd51 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -582,16 +582,22 @@ void LocalPlayer::updateDrawStateAndFlags(bool forceUpdate) bool sneak = ptrNpcStats.getMovementFlag(CreatureStats::Flag_Sneak); bool forceJump = ptrNpcStats.getMovementFlag(CreatureStats::Flag_ForceJump); bool forceMoveJump = ptrNpcStats.getMovementFlag(CreatureStats::Flag_ForceMoveJump); - bool jump = !world->isOnGround(player) && !world->isFlying(player); - static bool onJump = false; + + isFlying = world->isFlying(player); + bool isJumping = !world->isOnGround(player) && !isFlying; + + // We need to send a new packet at the end of jumping and flying too, + // so keep track of what we were doing last frame + static bool wasJumping = false; + static bool wasFlying = false; MWMechanics::DrawState_ state = player.getClass().getNpcStats(player).getDrawState(); static MWMechanics::DrawState_ oldState = player.getClass().getNpcStats(player).getDrawState(); - //static float timer = 0; + if (oldRun != run || oldSneak != sneak || oldForceJump != forceJump - || oldForceMoveJump != forceMoveJump || oldState != state || - ((jump || onJump)/* && (timer += MWBase::Environment::get().getFrameDuration() )> 0.5*/) + || oldForceMoveJump != forceMoveJump || oldState != state + || wasJumping || isJumping || wasFlying || isFlying || forceUpdate) { oldSneak = sneak; @@ -599,7 +605,9 @@ void LocalPlayer::updateDrawStateAndFlags(bool forceUpdate) oldForceJump = forceJump; oldForceMoveJump = forceMoveJump; oldState = state; - onJump = jump; + + wasFlying = isFlying; + wasJumping = isJumping; movementFlags = 0; #define __SETFLAG(flag, value) (value) ? (movementFlags | flag) : (movementFlags & ~flag) @@ -607,7 +615,7 @@ void LocalPlayer::updateDrawStateAndFlags(bool forceUpdate) movementFlags = __SETFLAG(CreatureStats::Flag_Sneak, sneak); movementFlags = __SETFLAG(CreatureStats::Flag_Run, run); movementFlags = __SETFLAG(CreatureStats::Flag_ForceJump, forceJump); - movementFlags = __SETFLAG(CreatureStats::Flag_ForceJump, jump); + movementFlags = __SETFLAG(CreatureStats::Flag_ForceJump, isJumping); movementFlags = __SETFLAG(CreatureStats::Flag_ForceMoveJump, forceMoveJump); #undef __SETFLAG @@ -619,13 +627,12 @@ void LocalPlayer::updateDrawStateAndFlags(bool forceUpdate) else if (state == MWMechanics::DrawState_Spell) drawState = 2; - if (jump) + if (isJumping) mwmp::Main::get().getLocalPlayer()->updatePosition(true); // fix position after jump; RakNet::BitStream bs; getNetworking()->getPlayerPacket((RakNet::MessageID) ID_PLAYER_DRAWSTATE)->Packet(&bs, this, true); getNetworking()->sendData(&bs); - //timer = 0; } } diff --git a/components/openmw-mp/Base/BasePlayer.hpp b/components/openmw-mp/Base/BasePlayer.hpp index e30cb09ed..e4a1e04f5 100644 --- a/components/openmw-mp/Base/BasePlayer.hpp +++ b/components/openmw-mp/Base/BasePlayer.hpp @@ -163,7 +163,6 @@ namespace mwmp RakNet::RakNetGUID guid; GUIMessageBox guiMessageBox; - ESM::Class charClass; int month; int day; double hour; @@ -178,16 +177,19 @@ namespace mwmp bool consoleAllowed; bool ignorePosPacket; + unsigned int movementFlags; + char movementAnim; + char drawState; + bool isFlying; + ESM::Position position; ESM::Position direction; ESM::Cell cell; ESM::NPC npc; ESM::NpcStats npcStats; ESM::CreatureStats creatureStats; + ESM::Class charClass; Item equipedItems[19]; - unsigned int movementFlags; - char movementAnim; - char drawState; Attack attack; std::string birthsign; std::string chatMessage; diff --git a/components/openmw-mp/Packets/Player/PacketPlayerDrawState.cpp b/components/openmw-mp/Packets/Player/PacketPlayerDrawState.cpp index 5bcfa1d45..b8d2972a9 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerDrawState.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerDrawState.cpp @@ -15,6 +15,6 @@ void mwmp::PacketPlayerDrawState::Packet(RakNet::BitStream *bs, mwmp::BasePlayer PlayerPacket::Packet(bs, player, send); RW(player->movementFlags, send); - RW(player->drawState, send); + RW(player->isFlying, send); }