Advertisement
Guest User

Untitled

a guest
Oct 21st, 2016
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.71 KB | None | 0 0
  1. #include "StdAfx.h"
  2. #include "Character.h"
  3. #include "Movement/CharacterMovement.h"
  4. #include "Animations/CharacterAnimations.h"
  5. #include "Path/CharacterPath.h"
  6.  
  7. //for path finding
  8. #include "Player/Player.h"
  9. #include "Player/Movement/PlayerMovement.h"
  10.  
  11. #include "ISimpleDamageable.h"
  12.  
  13. #include "Game/GameFactory.h"
  14. #include "Game/GameRules.h"
  15.  
  16. #include "FlowNodes/Helpers/FlowGameEntityNode.h"
  17.  
  18. #include <CryRenderer/IRenderAuxGeom.h>
  19.  
  20. //#include <CryPhysics/IPhysics.h>
  21.  
  22.  
  23. class CCharacterRegistrator
  24.     : public IEntityRegistrator
  25.     , public CCharacter::SExternalCVars
  26. {
  27.     virtual void Register() override
  28.     {
  29.         //CGameFactory::RegisterGameObject<CCharacter>("Character");
  30.         // Finally, register the entity class so that instances can be created later on either via Launcher or Editor
  31.         CCharacter::Register();
  32.        
  33.         CGameFactory::RegisterGameObjectExtension<CCharacterMovement>("CharacterMovement");
  34.         CGameFactory::RegisterGameObjectExtension<CCharacterAnimations>("CharacterAnimations");
  35.         CGameFactory::RegisterGameObjectExtension<CCharacterPath>("CharacterPath");
  36.  
  37.         RegisterCVars();
  38.  
  39.  
  40.     }
  41.  
  42.     void RegisterCVars()
  43.     {
  44.         REGISTER_CVAR2("ch_mass", &m_mass, 50.f, VF_CHEAT, "Mass of the player entity in kg");
  45.         REGISTER_CVAR2("ch_moveSpeed", &m_moveSpeed, 4.0f, VF_CHEAT, "Speed at which the player moves");
  46.  
  47.  
  48.         REGISTER_CVAR2("ch_eyeHeight", &m_playerEyeHeight, 0.935f, VF_CHEAT, "Height of the player's eyes from ground");
  49.  
  50.         m_pCharacterGeometry = REGISTER_STRING("ch_thirdPersonGeometry", "Assets/Objects/Characters/panda/panda.cdf", VF_CHEAT, "Sets the third person geometry to load");
  51.  
  52.         m_pCharacterMannequinContext = REGISTER_STRING("ch_thirdPersonMannequinContext", "Character", VF_CHEAT, "The name of the third person context used in Mannequin");
  53.         m_pCharacterAnimationDatabase = REGISTER_STRING("ch_thirdPersonAnimationDatabase", "Assets/Animations/Mannequin/ADB/panda.adb", VF_CHEAT, "Path to the animation database file to load");
  54.         m_pCharacterControllerDefinition = REGISTER_STRING("ch_thirdPersonControllerDefinition", "Animations/Mannequin/ADB/pandaControllerDefinition.xml", VF_CHEAT, "Path to the controller definition file to load");
  55.     }
  56. };
  57.  
  58. CCharacterRegistrator g_playerRegistrator;
  59.  
  60. CCharacter::CCharacter()
  61.     : m_pMovement(nullptr)
  62.     , m_bAlive(false)
  63.     , m_bHit(false)
  64.     , m_pPlayer(nullptr)
  65.     , m_pPath(nullptr)
  66.     , fgActionTryToFindPlayer(false)
  67. {
  68.  
  69. }
  70.  
  71. CCharacter::~CCharacter()
  72. {
  73.  
  74. }
  75.  
  76. const CCharacter::SExternalCVars &CCharacter::GetCVars() const
  77. {
  78.     return g_playerRegistrator;
  79. }
  80.  
  81. bool CCharacter::Init(IGameObject *pGameObject)
  82. {
  83.     if (!CNativeEntityBase::Init(pGameObject))
  84.         return false;
  85.  
  86.     SetGameObject(pGameObject);
  87.  
  88.     return true;
  89. }
  90.  
  91. void CCharacter::PostInit(IGameObject *pGameObject)
  92. {
  93.     CNativeEntityBase::PostInit(pGameObject);
  94.  
  95.     pGameObject->EnablePhysicsEvent(true, eEPE_OnCollisionLogged);
  96.  
  97.     const int requiredEvents[] = { eGFE_OnCollision };
  98.     pGameObject->UnRegisterExtForEvents(this, NULL, 0);
  99.     pGameObject->RegisterExtForEvents(this, requiredEvents, sizeof(requiredEvents) / sizeof(int));
  100.  
  101.     m_pMovement = static_cast<CCharacterMovement *>(GetGameObject()->AcquireExtension("CharacterMovement"));
  102.     m_pAnimations = static_cast<CCharacterAnimations *>(GetGameObject()->AcquireExtension("CharacterAnimations"));
  103.     m_pPath = static_cast<CCharacterPath *>(GetGameObject()->AcquireExtension("CharacterPath"));
  104.  
  105.     //gEnv->pGame->GetIGameFramework()->GetIActorSystem()->AddActor(GetEntityId(), this);
  106.  
  107.     //pGameObject->EnableUpdateSlot(this, 0);
  108. }
  109.  
  110. void CCharacter::ProcessEvent(SEntityEvent& event)
  111. {
  112.     switch (event.event)
  113.     {
  114.     case ENTITY_EVENT_START_LEVEL:
  115.         // Editor specific, physicalize on reset, property change or transform change
  116.     case ENTITY_EVENT_RESET:
  117.     {
  118.  
  119.             // Make sure to revive player when respawning in Editor
  120.             Reset();
  121.            
  122.             m_pPath->InitAI();
  123.             break;
  124.     }
  125.     case ENTITY_EVENT_EDITOR_PROPERTY_CHANGED:
  126.     case ENTITY_EVENT_XFORM_FINISHED_EDITOR:
  127.         Reset();
  128.         break;
  129.     case ENTITY_EVENT_HIDE:
  130.     case ENTITY_EVENT_UNHIDE:
  131.         break;
  132.     }
  133. }
  134.  
  135. void CCharacter::Update(SEntityUpdateContext& ctx, int updateSlot)
  136. {
  137.     //if (fgActionTryToFindPlayer)
  138.     //{
  139.  
  140.     // 
  141.     //  Vec3 playerPos = m_pPlayer->GetMovement()->GetWorldPosition();
  142.     //  Vec3 characterPos = GetEntity()->GetWorldPos();
  143.  
  144.     //  float distance = (characterPos - playerPos).len();
  145.  
  146.     //  // if near player stop
  147.     //  if (distance < 2.0f)
  148.     //  {
  149.     //      m_pPath->CancelCurrentRequest();
  150.     //      m_pPath->ClearMovementState();
  151.     //      fgActionTryToFindPlayer = false;
  152.     //  }
  153.     //  // else, try to reach player
  154.  
  155.     //}
  156. }
  157.  
  158. void CCharacter::Reset()
  159. {
  160.     // Note that this implementation does not handle the concept of death, SetHealth(0) will still revive the player.
  161.     //if (m_bAlive)
  162.     //  return;
  163.  
  164.     m_bAlive = true;
  165.     m_bHit = false;
  166.  
  167.     // Unhide the entity in case hidden by the Editor
  168.     GetEntity()->Hide(false);
  169.  
  170.  
  171.     // Make sure that the player spawns upright
  172.     GetEntity()->SetWorldTM(Matrix34::Create(Vec3(1.0, 1.0, 1.0), IDENTITY, GetEntity()->GetWorldPos()));
  173.  
  174.     // Set the player geometry, this also triggers physics proxy creation
  175.     SetCharacterModel();
  176. }
  177.  
  178. void CCharacter::SetCharacterModel()
  179. {
  180.     // Load the third person model
  181.     //GetEntity()->LoadCharacter(eGeometry_Character, GetCVars().m_pCharacterGeometry->GetString());
  182.  
  183.     // Do the same for animations so that Mannequin data can be initialized
  184.     m_pAnimations->OnCharacterModelChanged();
  185.  
  186.     // Now create the physical representation of the entity
  187.     m_pMovement->Physicalize();
  188.     m_pMovement->PhysicalizeAfter();
  189.  
  190.     StartColor();
  191. }
  192.  
  193. void CCharacter::OutputAllFG()
  194. {
  195.     OutputFG_IsGrouded(m_pMovement->IsOnGround());
  196.     OutputFG_Direction(m_pMovement->GetLocalMoveDirection());
  197.     OutputFG_EntityId(GetEntityId());
  198.    
  199.     if (lastSpeed > 0.01f)
  200.         OutputFG_IsMove();
  201.  
  202.     OutputFG_Speed(lastSpeed);
  203. }
  204.  
  205. void CCharacter::OutputFG_IsMove()
  206. {
  207.     TFlowInputData data;
  208.     data.SetUserFlag(true);
  209.     ActivateFlowNodeOutput(eOutputPort_IsMove, data);
  210. }
  211.  
  212. void CCharacter::OutputFG_Speed(float value)
  213. {
  214.     TFlowInputData data;
  215.     data.SetUserFlag(true);
  216.     data.Set<float>(value);
  217.     ActivateFlowNodeOutput(eOutputPort_Speed, data);
  218. }
  219.  
  220. void CCharacter::OutputFG_EntityId(EntityId value)
  221. {
  222.     TFlowInputData data;
  223.     data.SetUserFlag(true);
  224.     data.Set<EntityId>(value);
  225.     ActivateFlowNodeOutput(eOutputPort_EntityId, data);
  226. }
  227.  
  228. void CCharacter::OutputFG_Direction(Vec3 value)
  229. {
  230.     TFlowInputData data;
  231.     data.SetUserFlag(true);
  232.     data.Set<Vec3>(value);
  233.     ActivateFlowNodeOutput(eOutputPort_Direction, data);
  234. }
  235.  
  236. void CCharacter::OutputFG_IsGrouded(bool value)
  237. {
  238.     TFlowInputData data;
  239.     data.SetUserFlag(true);
  240.     data.Set<bool>(value);
  241.     ActivateFlowNodeOutput(eOutputPort_IsGrounded, data);
  242. }
  243.  
  244. void CCharacter::HandleEvent(const SGameObjectEvent &event)
  245. {
  246.     // Handle the OnCollision event, in order to have the entity removed on collision
  247.     if (event.event == eGFE_OnCollision)
  248.     {
  249.         // Collision info can be retrieved using the event pointer
  250.         //EventPhysCollision *physCollision = reinterpret_cast<EventPhysCollision *>(event.ptr);
  251.     }
  252. }
  253.  
  254. void CCharacter::StartColor()
  255. {
  256.     //// clone and red
  257.     //IStatObj* ob = GetEntity()->GetStatObj(0);
  258.     //IMaterial* pMaterial = ob->GetMaterial();
  259.     //IMaterial* pMaterialClone = gEnv->p3DEngine->GetMaterialManager()->CloneMaterial(pMaterial);
  260.     //pMaterialClone->SetGetMaterialParamVec3("diffuse", Vec3(1.0f, 0.0f, 0.0f), false);
  261.     //ob->SetMaterial(pMaterialClone);
  262.  
  263.     ICharacterInstance* const pCharacterInstance = GetEntity()->GetCharacter(CCharacter::eGeometry_Character);
  264.     IMaterial* pMaterial = pCharacterInstance->GetMaterial();
  265.     pMaterial->SetGetMaterialParamVec3("diffuse", Vec3(0.0f, 1.0f, 0.0f), false);
  266. }
  267.  
  268. void CCharacter::MarkAsHited()
  269. {
  270.     if (m_bHit)
  271.     {
  272.         ICharacterInstance* const pCharacterInstance = GetEntity()->GetCharacter(CCharacter::eGeometry_Character);
  273.        
  274.        
  275.        
  276.         IMaterial* pMaterial = pCharacterInstance->GetMaterial();
  277.        
  278.         IMaterial* pMaterialClone = gEnv->p3DEngine->GetMaterialManager()->CloneMaterial(pMaterial);
  279.         pMaterialClone->SetGetMaterialParamVec3("diffuse", Vec3(1.0f, 0.0f, 0.0f), false);
  280.         m_bHit = true;
  281.  
  282.         pCharacterInstance->SetIMaterial_Instance(pMaterialClone);
  283.  
  284.  
  285.         //IEntityPhysicalProxy* pProxy = (IEntityPhysicalProxy*)GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS);
  286.  
  287.         //IPhysicalEntity* phy = GetEntity()->GetPhysics();
  288.        
  289.  
  290.  
  291.     }
  292.     //IEntityRenderProxy* pProxy = (IEntityRenderProxy *)GetEntity()->GetProxy(ENTITY_PROXY_RENDER);
  293.     //pProxy->SetOpacity(0.5f);
  294. }
  295.  
  296. // Static function
  297. void CCharacter::Register()
  298. {
  299.     auto properties = new SNativeEntityPropertyInfo[eNumProperties];
  300.     memset(properties, 0, sizeof(SNativeEntityPropertyInfo) * eNumProperties);
  301.  
  302.     RegisterEntityProperty<bool>(properties, eProperty_Active, "Active", "1", "", 0, 1);
  303.  
  304.     //RegisterEntityProperty<float>(properties, eProperty_Radius, "Radius", "4", "", 0.1f, 100.f);
  305.  
  306.     // Finally, register the entity class so that instances can be created later on either via Launcher or Editor
  307.     CGameFactory::RegisterNativeEntity<CCharacter>("Character", "UserStuff", "character.bmp", 0u, properties, eNumProperties);
  308.  
  309.     // Create flownode
  310.     CGameEntityNodeFactory &nodeFactory = CGameFactory::RegisterEntityFlowNode("Character");
  311.  
  312.     // Define input ports, and the callback function for when they are triggered
  313.     std::vector<SInputPortConfig> inputs;
  314.     inputs.push_back(InputPortConfig_Void("TurnOn", "Turns the Area on"));
  315.     inputs.push_back(InputPortConfig_Void("TurnOff", "Turns the Area off"));
  316.     inputs.push_back(InputPortConfig_Void("GetStates", "Query Character states into outputs"));
  317.     inputs.push_back(InputPortConfig_Void("TryToFindPlayer", "Query Character for going closer to the Player"));
  318.  
  319.     nodeFactory.AddInputs(inputs, OnFlowgraphActivation);
  320.  
  321.     std::vector<SOutputPortConfig> outputs;
  322.     outputs.push_back(OutputPortConfig_Void("IsMove", "If character moves"));
  323.     outputs.push_back(OutputPortConfig<float>("Speed", "Character speed"));
  324.     outputs.push_back(OutputPortConfig<int>("EntityId", "Character Entity id"));
  325.     outputs.push_back(OutputPortConfig<Vec3>("Direction", "Move Direction"));
  326.     outputs.push_back(OutputPortConfig<bool>("IsGrounded", "Character on ground"));
  327.     //outputs.push_back(OutputPortConfig_AnyType("IsActive", "If player leave area"));
  328.     nodeFactory.AddOutputs(outputs);
  329.  
  330.  
  331.     // Mark the factory as complete, indicating that there will be no additional ports
  332.     nodeFactory.Close();
  333. }
  334.  
  335. void CCharacter::OnFlowgraphActivation(EntityId entityId, IFlowNode::SActivationInfo *pActInfo, const class CFlowGameEntityNode *pNode)
  336. {
  337.     if (auto *pCharacter = static_cast<CCharacter *>(QueryExtension(entityId)))
  338.     {
  339.         if (IsPortActive(pActInfo, eInputPort_TurnOn))
  340.         {
  341.             pCharacter->GetEntity()->Hide(false);
  342.  
  343.         }
  344.         else if (IsPortActive(pActInfo, eInputPort_TurnOff))
  345.         {
  346.             pCharacter->GetEntity()->Hide(true);
  347.         }
  348.         else if (IsPortActive(pActInfo, eInputPort_GetState))
  349.         {
  350.             pCharacter->OutputAllFG();
  351.         }
  352.         else if (IsPortActive(pActInfo, eInputPort_TryToFindPlayer))
  353.         {
  354.             pCharacter->FGAction_TryToFindPlayer();
  355.         }
  356.  
  357.     }
  358. }
  359.  
  360. void CCharacter::FindPlayer()
  361. {
  362.     // We only handle default spawning below for the Launcher
  363.     // Editor has special logic in CEditorGame
  364.     if (gEnv->IsEditor())
  365.         return;
  366.  
  367.     // Spawn at first default spawner
  368.     auto *pEntityIterator = gEnv->pEntitySystem->GetEntityIterator();
  369.     pEntityIterator->MoveFirst();
  370.  
  371.     auto *pSpawnerClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Player");
  372.     auto extensionId = gEnv->pGame->GetIGameFramework()->GetIGameObjectSystem()->GetID("Player");
  373.  
  374.     while (!pEntityIterator->IsEnd())
  375.     {
  376.         IEntity *pEntity = pEntityIterator->Next();
  377.  
  378.         if (pEntity->GetClass() != pSpawnerClass)
  379.             continue;
  380.  
  381.         auto *pGameObject = gEnv->pGame->GetIGameFramework()->GetGameObject(pEntity->GetId());
  382.         if (pGameObject == nullptr)
  383.             continue;
  384.  
  385.         auto *pPlayer = static_cast<CPlayer *>(pGameObject->QueryExtension(extensionId));
  386.         if (pPlayer == nullptr)
  387.             continue;
  388.  
  389.         //pSpawner->SpawnEntity(*GetEntity());
  390.         m_pPlayer = pPlayer;
  391.         // add
  392.  
  393.         break;
  394.     }
  395. }
  396.  
  397. void CCharacter::FGAction_TryToFindPlayer()
  398. {
  399.     if (gEnv->IsEditor())
  400.         return;
  401.  
  402.     if (m_pPlayer == nullptr)
  403.         FindPlayer(); // get pointer to m_pPlayer from world
  404.  
  405.     if (m_pPlayer != nullptr)
  406.     {
  407.         Vec3 playerPos = m_pPlayer->GetMovement()->GetWorldPosition();
  408.         Vec3 characterPos = GetEntity()->GetWorldPos();
  409.  
  410.         float distance = (characterPos - playerPos).len();
  411.  
  412.  
  413.         bool isCharacterMoving = m_pPath->IsProcessingRequest();
  414.  
  415.         if (isCharacterMoving)
  416.             m_pPath->CancelCurrentRequest();
  417.  
  418.         // only if player do not near
  419.         if (distance > 3.0f)
  420.         {
  421.             m_pPath->CancelCurrentRequest();
  422.             m_pPath->RequestMoveTo(playerPos);
  423.             //fgActionTryToFindPlayer = true;
  424.         }
  425.         else
  426.         {
  427.             m_pPath->CancelCurrentRequest();
  428.             //m_pPath->ClearMovementState();
  429.             //fgActionTryToFindPlayer = false;
  430.         }
  431.     }
  432. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement