[General] Make all flying players fly correctly, including TCL users

0.6.1
David Cernat 8 years ago
parent 48125913c3
commit e6bc7ad463

@ -16,6 +16,7 @@
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/mechanicsmanagerimp.hpp" #include "../mwmechanics/mechanicsmanagerimp.hpp"
#include "../mwmechanics/spellcasting.hpp"
#include "../mwworld/action.hpp" #include "../mwworld/action.hpp"
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
@ -220,12 +221,12 @@ void DedicatedPlayer::move(float dt)
ESM::Position refPos = ptr.getRefData().getPosition(); ESM::Position refPos = ptr.getRefData().getPosition();
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
{ {
osg::Vec3f lerp = Lerp(refPos.asVec3(), position.asVec3(), dt * 15); osg::Vec3f lerp = Lerp(refPos.asVec3(), position.asVec3(), dt * 15);
refPos.pos[0] = lerp.x(); refPos.pos[0] = lerp.x();
refPos.pos[1] = lerp.y(); refPos.pos[1] = lerp.y();
refPos.pos[2] = lerp.z(); refPos.pos[2] = lerp.z();
world->moveObject(ptr, refPos.pos[0], refPos.pos[1], refPos.pos[2]); world->moveObject(ptr, refPos.pos[0], refPos.pos[1], refPos.pos[2]);
} }
@ -265,7 +266,6 @@ void Players::update(float dt)
if (ptrNpcStats->isDead()) if (ptrNpcStats->isDead())
ptrNpcStats->resurrect(); ptrNpcStats->resurrect();
ptrNpcStats->setAttacked(false); ptrNpcStats->setAttacked(false);
ptrNpcStats->getAiSequence().stopCombat(); ptrNpcStats->getAiSequence().stopCombat();
@ -429,8 +429,24 @@ DedicatedPlayer *Players::getPlayer(const MWWorld::Ptr &ptr)
void DedicatedPlayer::updateDrawState() void DedicatedPlayer::updateDrawState()
{ {
using namespace MWMechanics; 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) if (drawState == 0)
ptr.getClass().getNpcStats(ptr).setDrawState(DrawState_Nothing); ptr.getClass().getNpcStats(ptr).setDrawState(DrawState_Nothing);
else if (drawState == 1) else if (drawState == 1)

@ -582,16 +582,22 @@ void LocalPlayer::updateDrawStateAndFlags(bool forceUpdate)
bool sneak = ptrNpcStats.getMovementFlag(CreatureStats::Flag_Sneak); bool sneak = ptrNpcStats.getMovementFlag(CreatureStats::Flag_Sneak);
bool forceJump = ptrNpcStats.getMovementFlag(CreatureStats::Flag_ForceJump); bool forceJump = ptrNpcStats.getMovementFlag(CreatureStats::Flag_ForceJump);
bool forceMoveJump = ptrNpcStats.getMovementFlag(CreatureStats::Flag_ForceMoveJump); 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(); MWMechanics::DrawState_ state = player.getClass().getNpcStats(player).getDrawState();
static MWMechanics::DrawState_ oldState = player.getClass().getNpcStats(player).getDrawState(); static MWMechanics::DrawState_ oldState = player.getClass().getNpcStats(player).getDrawState();
//static float timer = 0;
if (oldRun != run if (oldRun != run
|| oldSneak != sneak || oldForceJump != forceJump || oldSneak != sneak || oldForceJump != forceJump
|| oldForceMoveJump != forceMoveJump || oldState != state || || oldForceMoveJump != forceMoveJump || oldState != state
((jump || onJump)/* && (timer += MWBase::Environment::get().getFrameDuration() )> 0.5*/) || wasJumping || isJumping || wasFlying || isFlying
|| forceUpdate) || forceUpdate)
{ {
oldSneak = sneak; oldSneak = sneak;
@ -599,7 +605,9 @@ void LocalPlayer::updateDrawStateAndFlags(bool forceUpdate)
oldForceJump = forceJump; oldForceJump = forceJump;
oldForceMoveJump = forceMoveJump; oldForceMoveJump = forceMoveJump;
oldState = state; oldState = state;
onJump = jump;
wasFlying = isFlying;
wasJumping = isJumping;
movementFlags = 0; movementFlags = 0;
#define __SETFLAG(flag, value) (value) ? (movementFlags | flag) : (movementFlags & ~flag) #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_Sneak, sneak);
movementFlags = __SETFLAG(CreatureStats::Flag_Run, run); movementFlags = __SETFLAG(CreatureStats::Flag_Run, run);
movementFlags = __SETFLAG(CreatureStats::Flag_ForceJump, forceJump); movementFlags = __SETFLAG(CreatureStats::Flag_ForceJump, forceJump);
movementFlags = __SETFLAG(CreatureStats::Flag_ForceJump, jump); movementFlags = __SETFLAG(CreatureStats::Flag_ForceJump, isJumping);
movementFlags = __SETFLAG(CreatureStats::Flag_ForceMoveJump, forceMoveJump); movementFlags = __SETFLAG(CreatureStats::Flag_ForceMoveJump, forceMoveJump);
#undef __SETFLAG #undef __SETFLAG
@ -619,13 +627,12 @@ void LocalPlayer::updateDrawStateAndFlags(bool forceUpdate)
else if (state == MWMechanics::DrawState_Spell) else if (state == MWMechanics::DrawState_Spell)
drawState = 2; drawState = 2;
if (jump) if (isJumping)
mwmp::Main::get().getLocalPlayer()->updatePosition(true); // fix position after jump; mwmp::Main::get().getLocalPlayer()->updatePosition(true); // fix position after jump;
RakNet::BitStream bs; RakNet::BitStream bs;
getNetworking()->getPlayerPacket((RakNet::MessageID) ID_PLAYER_DRAWSTATE)->Packet(&bs, this, true); getNetworking()->getPlayerPacket((RakNet::MessageID) ID_PLAYER_DRAWSTATE)->Packet(&bs, this, true);
getNetworking()->sendData(&bs); getNetworking()->sendData(&bs);
//timer = 0;
} }
} }

@ -163,7 +163,6 @@ namespace mwmp
RakNet::RakNetGUID guid; RakNet::RakNetGUID guid;
GUIMessageBox guiMessageBox; GUIMessageBox guiMessageBox;
ESM::Class charClass;
int month; int month;
int day; int day;
double hour; double hour;
@ -178,16 +177,19 @@ namespace mwmp
bool consoleAllowed; bool consoleAllowed;
bool ignorePosPacket; bool ignorePosPacket;
unsigned int movementFlags;
char movementAnim;
char drawState;
bool isFlying;
ESM::Position position; ESM::Position position;
ESM::Position direction; ESM::Position direction;
ESM::Cell cell; ESM::Cell cell;
ESM::NPC npc; ESM::NPC npc;
ESM::NpcStats npcStats; ESM::NpcStats npcStats;
ESM::CreatureStats creatureStats; ESM::CreatureStats creatureStats;
ESM::Class charClass;
Item equipedItems[19]; Item equipedItems[19];
unsigned int movementFlags;
char movementAnim;
char drawState;
Attack attack; Attack attack;
std::string birthsign; std::string birthsign;
std::string chatMessage; std::string chatMessage;

@ -15,6 +15,6 @@ void mwmp::PacketPlayerDrawState::Packet(RakNet::BitStream *bs, mwmp::BasePlayer
PlayerPacket::Packet(bs, player, send); PlayerPacket::Packet(bs, player, send);
RW(player->movementFlags, send); RW(player->movementFlags, send);
RW(player->drawState, send); RW(player->drawState, send);
RW(player->isFlying, send);
} }

Loading…
Cancel
Save