⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 player.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

#include "game/player.h"

#include "platform/platform.h"
#include "platform/profiler.h"
#include "dgl/dgl.h"
#include "dgl/materialPropertyMap.h"
#include "math/mMath.h"
#include "core/stringTable.h"
#include "core/bitStream.h"
#include "core/dnet.h"
#include "core/resManager.h"
#include "console/simBase.h"
#include "console/console.h"
#include "console/consoleTypes.h"
#include "collision/extrudedPolyList.h"
#include "collision/clippedPolyList.h"
#include "collision/earlyOutPolyList.h"
#include "sim/decalManager.h"
#include "ts/tsShapeInstance.h"
#include "audio/audioDataBlock.h"
#include "sceneGraph/sceneGraph.h"
#include "sceneGraph/sceneState.h"
#include "sceneGraph/detailManager.h"
#include "terrain/terrData.h"
#include "terrain/terrRender.h"
#include "terrain/waterBlock.h"
#include "game/game.h"
#include "game/moveManager.h"
#include "game/gameConnection.h"
#include "game/trigger.h"
#include "game/physicalZone.h"
#include "game/item.h"
#include "game/shadow.h"
#include "game/missionArea.h"
#include "game/fx/particleEngine.h"
#include "game/fx/splash.h"
#include "game/fx/cameraFXMgr.h"



//#define ENBABLE_RPG_COLLISION
//----------------------------------------------------------------------------


// Amount we try to stay out of walls by...
static F32 sWeaponPushBack = 0.03;

// Amount of time if takes to transition to a new action sequence.
static F32 sAnimationTransitionTime = 0.25;
static bool sUseAnimationTransitions = true;
static F32 sLandReverseScale = 0.25;
static F32 sStandingJumpSpeed = 2.0;
static F32 sJumpingThreshold = 4.0;
static F32 sSlowStandThreshSquared = 1.69;
static S32 sRenderMyPlayer = true;
static S32 sRenderMyItems = true;

// Chooses new action animations every n ticks.
static const F32 sNewAnimationTickTime = 4;
static const F32 sMountPendingTickWait = (13 * 32);

// Number of ticks before we pick non-contact animations
static const S32 sContactTickTime = 30;

// Downward velocity at which we consider the player falling
static const F32 sFallingThreshold = -10;

// Movement constants
static F32 sVerticalStepDot = 0.173;   // 80
static F32 sMinFaceDistance = 0.01;
static F32 sTractionDistance = 0.03;
static F32 sNormalElasticity = 0.01;
static U32 sMoveRetryCount = 5;

// Client prediction
static F32 sMinWarpTicks = 0.5;        // Fraction of tick at which instant warp occures
static S32 sMaxWarpTicks = 3;          // Max warp duration in ticks
static S32 sMaxPredictionTicks = 30;   // Number of ticks to predict

// Anchor point compression
const F32 sAnchorMaxDistance = 32;

//
static U32 sCollisionMoveMask = (TerrainObjectType      | InteriorObjectType   |
                                 WaterObjectType        | PlayerObjectType     |
                                 StaticShapeObjectType  | VehicleObjectType    |
                                 PhysicalZoneObjectType | StaticTSObjectType);

static U32 sServerCollisionContactMask = (sCollisionMoveMask |
                                          (ItemObjectType    |
                                           TriggerObjectType |
                                           CorpseObjectType));

static U32 sClientCollisionContactMask = sCollisionMoveMask | PhysicalZoneObjectType;

enum PlayerConstants {
   JumpSkipContactsMax = 8
};

//----------------------------------------------------------------------------
// Player shape animation sequences:

// look     Used to contol the upper body arm motion.  Must animate
//          vertically +-80 deg.
Player::Range Player::mArmRange(mDegToRad(-80.0f),mDegToRad(+80.0f));

// head     Used to control the direction the head is looking.  Must
//          animated vertically +-80 deg .
Player::Range Player::mHeadVRange(mDegToRad(-80.0f),mDegToRad(+80.0f));

// Action Animations:
PlayerData::ActionAnimationDef PlayerData::ActionAnimationList[NumTableActionAnims] =
{
   // *** WARNING ***
   // This array is indexed useing the enum values defined in player.h

   // Root is the default animation
	/// TGE_PlayerAnim
   //{ "root" },       // RootAnim, 
   { "idle" },       // IdleAnim,
   { "swimidle" },       // SwimIdleAnim,

   // These are selected in the move state based on velocity
	/// TGE_PlayerAnim
   { "walk",  { 0,+1,0 } },			// WalkAnim,
   { "walk",  { 0,-1,0 } },			// WalkBackwardAnim 与walk相同,在pickAction时,设为反方向播放
   { "run",  { 0,+1,0 } },				// RunAnim,
   { "run",  { 0,-1,0 } },				// RunBackwardAnim 与run相同,在pickAction时,设为反方向播放

   { "walk2",  { 0,+1,0 } },			// Walk2Anim,
   { "walk2",  { 0,-1,0 } },			// Walk2BackwardAnim 与walk相同,在pickAction时,设为反方向播放
   { "run2",  { 0,+1,0 } },			// Run2Anim,
   { "run2",  { 0,-1,0 } },			// Run2BackwardAnim 与run相同,在pickAction时,设为反方向播放

   { "swim",  { 0,+1,0 } },			// SwimAnim,
   { "swim",  { 0,-1,0 } },			// SwimBackwardAnim 与swim相同,在pickAction时,设为反方向播放


   //{ "run",  { 0,+1,0 } },			// RunForwardAnim,
   //{ "back", { 0,-1,0 } },       // BackBackwardAnim
   //{ "side", { -1,0,0 } },       // SideLeftAnim,

   // These are set explicitly based on player actions
   { "agree" },       // AgreeAnim
   { "disagree" },       // DisagreeAnim
   { "bow" },       // BowAnim
   { "wave" },       // WaveAnim
   { "point" },       // PointAnim
   { "dance" },       // DanceAnim

   { "fall" },       // FallAnim
   { "jump" },       // JumpAnim
   { "standjump" },  // StandJumpAnim
   { "land" },       // LandAnim
};


//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------

IMPLEMENT_CO_DATABLOCK_V1(PlayerData);

PlayerData::PlayerData()
{
   renderFirstPerson = true;
   pickupRadius = 0;
   minLookAngle = -1.4;
   maxLookAngle = 1.4;
   maxFreelookAngle = 3.0;
   maxTimeScale = 1.5;

   mass = 9;
   maxEnergy =  60;

   runForce = 40 * 9;
   runEnergyDrain = 0;
   minRunEnergy = 0;
   maxForwardSpeed = 10;
   maxBackwardSpeed = 10;
   maxSideSpeed = 10;
   maxUnderwaterForwardSpeed = 10;
   maxUnderwaterBackwardSpeed = 10;
   maxUnderwaterSideSpeed = 10;
#ifdef TGE_RPG
	m_fRunRate		= 1.5f;
#endif

   maxStepHeight = 1;
   runSurfaceAngle = 80;

   recoverDelay = 30;
   recoverRunForceScale = 1;

   jumpForce = 75;
   jumpEnergyDrain = 0;
   minJumpEnergy = 0;
   jumpSurfaceAngle = 78;
   jumpDelay = 30;
   minJumpSpeed = 500;
   maxJumpSpeed = 2 * minJumpSpeed;

   horizMaxSpeed = 80;
   horizResistSpeed = 38;
   horizResistFactor = 1;

   upMaxSpeed = 80;
   upResistSpeed = 38;
   upResistFactor = 1;

   minImpactSpeed = 25;

   decalData      = NULL;
   decalID        = 0;
   decalOffset      = 0.0f;

   lookAction = 0;

   // size of bounding box
   boxSize.set(1,1,2.3);

   // location of head, torso, legs
   boxHeadPercentage = 0.85;
   boxTorsoPercentage = 0.55;

   // damage locations
   boxHeadLeftPercentage  = 0;
   boxHeadRightPercentage = 1;
   boxHeadBackPercentage  = 0;
   boxHeadFrontPercentage = 1;

   for (S32 i = 0; i < MaxSounds; i++)
      sound[i] = 0;

   footPuffEmitter = NULL;
   footPuffID = 0;
   footPuffNumParts = 15;
   footPuffRadius = .25;

   dustEmitter = NULL;
   dustID = 0;

   splash = NULL;
   splashId = 0;
   splashVelocity = 1.0;
   splashAngle = 45.0;
   splashFreqMod = 300.0;
   splashVelEpsilon = 0.25;
   bubbleEmitTime = 0.4;

   medSplashSoundVel = 2.0;
   hardSplashSoundVel = 3.0;
   exitSplashSoundVel = 2.0;
   footSplashHeight = 0.1;

   dMemset( splashEmitterList, 0, sizeof( splashEmitterList ) );
   dMemset( splashEmitterIDList, 0, sizeof( splashEmitterIDList ) );

   genericShadowLevel = Player_GenericShadowLevel;
   noShadowLevel = Player_NoShadowLevel;

   groundImpactMinSpeed = 10.0;
   groundImpactShakeFreq.set( 10.0, 10.0, 10.0 );
   groundImpactShakeAmp.set( 20.0, 20.0, 20.0 );
   groundImpactShakeDuration = 1.0;
   groundImpactShakeFalloff = 10.0;
}

bool PlayerData::preload(bool server, char errorBuffer[256])
{
   if(!Parent::preload(server, errorBuffer))
      return false;

#ifdef TGE_RPG
   if(server)
		return true;
#endif

   // Resolve objects transmitted from server
   if (!server) 
	{
      for (S32 i = 0; i < MaxSounds; i++)
         if (sound[i])
            Sim::findObject(SimObjectId(sound[i]),sound[i]);
   }

   //
   runSurfaceCos = mCos(mDegToRad(runSurfaceAngle));
   jumpSurfaceCos = mCos(mDegToRad(jumpSurfaceAngle));
   if (minJumpEnergy < jumpEnergyDrain)
      minJumpEnergy = jumpEnergyDrain;

   // Validate some of the data
   if (recoverDelay > (1 << RecoverDelayBits) - 1) {
      recoverDelay = (1 << RecoverDelayBits) - 1;
      Con::printf("PlayerData:: Recover delay exceeds range (0-%d)",recoverDelay);
   }
   if (jumpDelay > (1 << JumpDelayBits) - 1) {
      jumpDelay = (1 << JumpDelayBits) - 1;
      Con::printf("PlayerData:: Jump delay exceeds range (0-%d)",jumpDelay);
   }

#ifdef TGE_RPG
	if(shape)
	{
#endif
   // Go ahead a pre-load the player shape
   TSShapeInstance* si = new TSShapeInstance(shape, false);
   TSThread* thread = si->addThread();

   // Extract ground transform velocity from animations
   // Get the named ones first so they can be indexed directly.
   ActionAnimation *dp = &actionList[0];
   for (int i = 0; i < NumTableActionAnims; i++,dp++)
   {
      ActionAnimationDef *sp = &ActionAnimationList[i];
      dp->name          = sp->name;
      dp->dir.set(sp->dir.x,sp->dir.y,sp->dir.z);
      dp->sequence      = shape->findSequence(sp->name);
      dp->velocityScale = true;
      dp->death         = false;
      if (dp->sequence != -1)
         getGroundInfo(si,thread,dp);

#ifdef TGE_RPG
		if(GameBase::g_bInGameWorld)
#endif
      AssertWarn(dp->sequence != -1, avar("PlayerData::preload - Unable to find named animation sequence '%s'!", sp->name));
   }
   for (int b = 0; b < shape->sequences.size(); b++)
   {
      if (!isTableSequence(b))
      {
         dp->sequence      = b;
         dp->name          = shape->getName(shape->sequences[b].nameIndex);
         dp->velocityScale = false;
         getGroundInfo(si,thread,dp++);
      }
   }
   actionCount = dp - actionList;
   AssertFatal(actionCount <= NumActionAnims, "Too many action animations!");
   delete si;


   // Resolve lookAction index
   dp = &actionList[0];
   const char *lookName = StringTable->insert("look");
   for (int c = 0; c < actionCount; c++,dp++)
      if (dp->name == lookName)
         lookAction = c;

   // Resolve spine
   spineNode[0] = shape->findNode("Bip01 Pelvis");
   spineNode[1] = shape->findNode("Bip01 Spine");
   spineNode[2] = shape->findNode("Bip01 Spine1");
   spineNode[3] = shape->findNode("Bip01 Spine2");
   spineNode[4] = shape->findNode("Bip01 Neck");
   spineNode[5] = shape->findNode("Bip01 Head");

   // Recoil animations
   recoilSequence[0] = shape->findSequence("light_recoil");
   recoilSequence[1] = shape->findSequence("medium_recoil");
   recoilSequence[2] = shape->findSequence("heavy_recoil");

#ifdef TGE_RPG
	}//if(shape)
#endif
   // Lookup shadow node (shadow center moves in synch with this node)
   shadowNode = spineNode[0];

   // Convert pickupRadius to a delta of boundingBox
   F32 dr = (boxSize.x > boxSize.y)? boxSize.x: boxSize.y;
   if (pickupRadius < dr)
      pickupRadius = dr;
   else
      if (pickupRadius > 2 * dr)
         pickupRadius = 2 * dr;
   pickupDelta = (S32)(pickupRadius - dr);

   // Validate jump speed
   if (maxJumpSpeed <= minJumpSpeed)
      maxJumpSpeed = minJumpSpeed + 0.1;

   // Load up all the emitters
   if (!footPuffEmitter && footPuffID != 0)
      if (!Sim::findObject(footPuffID, footPuffEmitter))
         Con::errorf(ConsoleLogEntry::General, "PlayerData::preload - Invalid packet, bad datablockId(footPuffEmitter): 0x%x", footPuffID);

   if (!decalData && decalID != 0 )
      if (!Sim::findObject(decalID, decalData))
         Con::errorf(ConsoleLogEntry::General, "PlayerData::preload - Invalid packet, bad datablockId(decalData): 0x%x", decalID);

   if (!dustEmitter && dustID != 0 )
      if (!Sim::findObject(dustID, dustEmitter))
         Con::errorf(ConsoleLogEntry::General, "PlayerData::preload - Invalid packet, bad datablockId(dustEmitter): 0x%x", dustID);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -