📄 player.cc
字号:
// predict using the last known move.
if (mPredictionCount-- <= 0)
{
PROFILE_END();
return;
}
move = &delta.move;
}
else
move = &NullMove;
}//if (!move)
///这里只能在server端调用,CLIENT端在advanceTime已经调用了
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
if (!isGhost())
{
updateAnimation(TickSec);
}
#endif
PROFILE_START(Player_PhysicsSection);
if(isServerObject() || (didRenderLastRender() || getControllingClient()))
{
updateWorkingCollisionSet();
updateState();
updateMove(move);
updateLookAnimation();
updateDeathOffsets();
updatePos();
}
PROFILE_END();
/// TGE_RPGClientCtrl 这里只能在server端调用,CLIENT端在advanceTime已经调用了
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
if (!isGhost())
{
// Animations are advanced based on frame rate on the
// client and must be ticked on the server.
updateActionThread();
updateAnimationTree(true);
}
#endif
}
PROFILE_END();
}
void Player::interpolateTick(F32 dt)
{
if (mControlObject)
mControlObject->interpolateTick(dt);
// Client side interpolation
Parent::interpolateTick(dt);
if(dt != 0.0f)
{
Point3F pos = delta.pos + delta.posVec * dt;
Point3F rot = delta.rot + delta.rotVec * dt;
mHead = delta.head + delta.headVec * dt;
setRenderPosition(pos,rot,dt);
// apply camera effects - is this the best place? - bramage
GameConnection* connection = GameConnection::getConnectionToServer();
if( connection->isFirstPerson() )
{
ShapeBase *obj = connection->getControlObject();
if( obj == this )
{
MatrixF curTrans = getRenderTransform();
curTrans.mul( gCamFXMgr.getTrans() );
Parent::setRenderTransform( curTrans );
}
}
}
else
{
mHead = delta.head;
setRenderPosition(delta.pos, delta.rot, 0);
}
updateLookAnimation();
delta.dt = dt;
}
void Player::advanceTime(F32 dt)
{
// Client side animations
Parent::advanceTime(dt);
updateActionThread();
updateAnimation(dt);
updateSplash();
updateFroth(dt);
updateWaterSounds(dt);
mLastPos = getPosition();
if (mImpactSound)
playImpactSound();
// update camera effects. Definitely need to find better place for this - bramage
if( isControlObject() )
{
if( mDamageState == Disabled || mDamageState == Destroyed )
{
// clear out all camera effects being applied to player if dead
gCamFXMgr.clear();
}
gCamFXMgr.update( dt );
}
}
bool Player::getAIMove(Move* move)
{
return false;
}
//----------------------------------------------------------------------------
void Player::setState(ActionState state, U32 recoverTicks)
{
if (state != mState) {
// Skip initialization if there is no manager, the state
// will get reset when the object is added to a manager.
if (isProperlyAdded()) {
switch (state) {
case RecoverState: {
mRecoverTicks = recoverTicks;
mReversePending = U32(F32(mRecoverTicks) / sLandReverseScale);
setActionThread(PlayerData::LandAnim, true, false, true, true);
break;
}
}
}
mState = state;
}
}
void Player::updateState()
{
switch (mState)
{
/// 以下为Action状态转移,由RecoverState -> MoveState
/// mRecoverTicks为0时,
/// a.mReversePending为true时,则transitionToSequence到其它Action
/// b.否则直接转移到其它action
case RecoverState:
if (mRecoverTicks-- == 0)
{
if (mReversePending)
{
// this serves and counter, and direction state
mRecoverTicks = mReversePending;
mActionAnimation.forward = false;
S32 seq = mDataBlock->actionList[mActionAnimation.action].sequence;
F32 pos = mShapeInstance->getPos(mActionAnimation.thread);
mShapeInstance->setTimeScale(mActionAnimation.thread, -sLandReverseScale);
mShapeInstance->transitionToSequence(mActionAnimation.thread,
seq, pos, sAnimationTransitionTime, true);
mReversePending = 0;
}
else
{
/// TGE_PlayerAnim
setState(WalkState);
//setState(MoveState);
}
} // Stand back up slowly only if not moving much-
else if (!mReversePending && mVelocity.lenSquared() > sSlowStandThreshSquared)
{
mActionAnimation.waitForEnd = false;
/// TGE_PlayerAnim
setState(WalkState);
//setState(MoveState);
}
break;
}
}
const char* Player::getStateName()
{
if (mDamageState != Enabled)
return "Dead";
if (isMounted())
return "Mounted";
if (mState == RecoverState)
return "Recover";
return "Move";
}
void Player::getDamageLocation(const Point3F& in_rPos, const char *&out_rpVert, const char *&out_rpQuad)
{
Point3F newPoint;
mWorldToObj.mulP(in_rPos, &newPoint);
F32 zHeight = mDataBlock->boxSize.z;
F32 zTorso = mDataBlock->boxTorsoPercentage;
F32 zHead = mDataBlock->boxHeadPercentage;
zTorso *= zHeight;
zHead *= zHeight;
if (newPoint.z <= zTorso)
out_rpVert = "legs";
else if (newPoint.z <= zHead)
out_rpVert = "torso";
else
out_rpVert = "head";
if(dStrcmp(out_rpVert, "head") != 0)
{
if (newPoint.y >= 0.0f)
{
if (newPoint.x <= 0.0f)
out_rpQuad = "front_left";
else
out_rpQuad = "front_right";
}
else
{
if (newPoint.x <= 0.0f)
out_rpQuad = "back_left";
else
out_rpQuad = "back_right";
}
}
else
{
F32 backToFront = mDataBlock->boxSize.x;
F32 leftToRight = mDataBlock->boxSize.y;
F32 backPoint = backToFront * (mDataBlock->boxHeadBackPercentage - 0.5);
F32 frontPoint = backToFront * (mDataBlock->boxHeadFrontPercentage - 0.5);
F32 leftPoint = leftToRight * (mDataBlock->boxHeadLeftPercentage - 0.5);
F32 rightPoint = leftToRight * (mDataBlock->boxHeadRightPercentage - 0.5);
S32 index = 0;
if (newPoint.y < backPoint)
index += 0;
else if (newPoint.y <= frontPoint)
index += 3;
else
index += 6;
if (newPoint.x < leftPoint)
index += 0;
else if (newPoint.x <= rightPoint)
index += 1;
else
index += 2;
switch (index)
{
case 0:
out_rpQuad = "left_back";
break;
case 1: out_rpQuad = "middle_back"; break;
case 2: out_rpQuad = "right_back"; break;
case 3: out_rpQuad = "left_middle"; break;
case 4: out_rpQuad = "middle_middle"; break;
case 5: out_rpQuad = "right_middle"; break;
case 6: out_rpQuad = "left_front"; break;
case 7: out_rpQuad = "middle_front"; break;
case 8: out_rpQuad = "right_front"; break;
default:
AssertFatal(0, "Bad non-tant index");
};
}
}
//----------------------------------------------------------------------------
void Player::updateMove(const Move* move)
{
delta.move = *move;
/// 触发器处理
// Trigger images
if (mDamageState == Enabled)
{
setImageTriggerState(0,move->trigger[0]);
setImageTriggerState(1,move->trigger[1]);
/// Run与Walk状态切换 TGE_PlayerAnim
if (move->trigger[3] && !isMounted())
{
if(mState == RunState)
mState = WalkState;
else if(mState == WalkState)
mState = RunState;
}
}
// Update current orientation
/// 更新人物面向的方向,截取人物头部转向范围、头部仰角
if (mDamageState == Enabled)
{
F32 prevZRot = mRot.z;
delta.headVec = mHead;
F32 p = move->pitch;
if (p > M_PI) p -= M_2PI;
mHead.x = mClampF(mHead.x + p,mDataBlock->minLookAngle,
mDataBlock->maxLookAngle);
F32 y = move->yaw;
if (y > M_PI) y -= M_2PI;
GameConnection* con = getControllingClient();
if (move->freeLook && ((isMounted() && getMountNode() == 0) || (con && !con->isFirstPerson())))
{
mHead.z = mClampF(mHead.z + y,
-mDataBlock->maxFreelookAngle,
mDataBlock->maxFreelookAngle);
}
else
{
mRot.z += y;
// Rotate the head back to the front, center horizontal
// as well if we're controlling another object.
mHead.z *= 0.5;
if (mControlObject)
mHead.x *= 0.5;
}
// constrain the range of mRot.z
while (mRot.z < 0)
mRot.z += M_2PI;
while (mRot.z > M_2PI)
mRot.z -= M_2PI;
delta.rot = mRot;
delta.rotVec.x = delta.rotVec.y = 0;
delta.rotVec.z = prevZRot - mRot.z;
if (delta.rotVec.z > M_PI)
delta.rotVec.z -= M_2PI;
else if (delta.rotVec.z < -M_PI)
delta.rotVec.z += M_2PI;
delta.head = mHead;
delta.headVec -= mHead;
}
MatrixF zRot;
zRot.set(EulerF(0, 0, mRot.z));
// Desired move direction & speed
/// 计算移动方向、速度(岸上速度、水中速度、前向、后向)
VectorF moveVec;
F32 moveSpeed;
/// TGE_PlayerAnim
if ((mState == WalkState || mState == RunState) && mDamageState == Enabled)
//if (mState == MoveState && mDamageState == Enabled)
{
zRot.getColumn(0,&moveVec);
moveVec *= move->x;
VectorF tv;
zRot.getColumn(1,&tv);
moveVec += tv * move->y;
// Clamp water movement
if (move->y > 0)
{
if( mWaterCoverage >= 0.9 )
moveSpeed = getMax(mDataBlock->maxUnderwaterForwardSpeed * move->y,
mDataBlock->maxUnderwaterSideSpeed * mFabs(move->x));
else
moveSpeed = getMax(mDataBlock->maxForwardSpeed * move->y,
mDataBlock->maxSideSpeed * mFabs(move->x));
}
else
{
if( mWaterCoverage >= 0.9 )
moveSpeed = getMax(mDataBlock->maxUnderwaterBackwardSpeed * mFabs(move->y),
mDataBlock->maxUnderwaterSideSpeed * mFabs(move->x));
else
moveSpeed = getMax(mDataBlock->maxBackwardSpeed * mFabs(move->y),
mDataBlock->maxSideSpeed * mFabs(move->x));
}
#ifdef TGE_RPG
/// Run状态速度加倍 TGE_PlayerAnim
moveSpeed += m_fMoveSpeed;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -