Engine inner working: Difference between revisions
		
		
		
		Jump to navigation
		Jump to search
		
| Line 43: | Line 43: | ||
|    APlaneshiftPlayerControllerBase::RequestAttack |    APlaneshiftPlayerControllerBase::RequestAttack | ||
|      UserManager::HandleAttack |      UserManager::HandleAttack (has knowledge of isPrimaryWeapon) | ||
|        UserManager::Attack  checks if alive, if frozen, IsAllowedToAttack, set target in front with linetrace |        UserManager::Attack  checks if alive, if frozen, IsAllowedToAttack, set target in front with linetrace | ||
|          CombatManager::AttackSomeone check if already attacking (locks double attack), cycle on all slots, check weapon requirements, and schedule attack for each |          CombatManager::AttackSomeone(isPrimaryWeapon) check if already attacking (locks double attack), cycle on all slots, check weapon requirements, and schedule attack for each | ||
|            psAttack::Attack (takes slot as input), schedules all attack events for combat resolution. +1 attack_cnt |            psAttack::Attack (takes slot as input), schedules all attack events for combat resolution. +1 attack_cnt | ||
|              UpsCombatAttackGameEvent::Trigger() -> combat resolution |              UpsCombatAttackGameEvent::Trigger() -> combat resolution | ||
Revision as of 16:37, 3 April 2021
Player loaded into the game
UPreGameHelper::RequestCharacter click on the selected character, then click on PLAY SpawnedChar = SpawnActor() creates the 3d model into the world SpawnedChar->Load() Assign the actor to the player controller PlayerController->Possess(SpawnedChar); SpawnedChar->PlayerTeleportToMainWorld() -> calls the BP function to iniatilize the timers client side
Wander Operation
 WanderOperation::Run()
    CalculateEdgeList()
         FindNearestWaypoint() finds start point
         GetActiveLocate() finds end point
         FindEdgeRoute() finds the route between start and end
    dest = GetNextPathPoint() gets the next path point (not the current one) and returns it
    StartMoveTo(dest) 
    
NPC Brain
 APlaneShiftGameState::BeginPlay()
  calls psNPCManager::Initialize()
      calls ReadNPCsFromDatabase()
         select * from sc_npc_definitions
         populates npcs TMap
    
 spawnManager->RepopulateLive();
   LoadAllNPCCharacterData
      SELECT characters.* where npc_spawn_rule>0
           char = SpawnActor()
           char->Load()
               if (IsNPC()) psAIController->SetBrain( using npcs TMap above)
When a perception happens it goes through:
  psNPCManager::TriggerEvent()
    checks all reactions with this event and it finds also the brains without pawn associated, so I added a check there to skip
Attack sequence
 APlaneshiftPlayerControllerBase::RequestAttack
   UserManager::HandleAttack (has knowledge of isPrimaryWeapon)
     UserManager::Attack  checks if alive, if frozen, IsAllowedToAttack, set target in front with linetrace
       CombatManager::AttackSomeone(isPrimaryWeapon) check if already attacking (locks double attack), cycle on all slots, check weapon requirements, and schedule attack for each
         psAttack::Attack (takes slot as input), schedules all attack events for combat resolution. +1 attack_cnt
           UpsCombatAttackGameEvent::Trigger() -> combat resolution
             psAttack::Affect If ranged check ammo, check again you can use weapon, 
               psAttack::AffectTarget deal the damage
           UpsCombatENDAttackEvent::Trigger() 
              ApsCharacter::EndAttack(), resets the attack lock (you can attack again). -1 attack_cnt
Main engine loop on startup
MyProjectServer.exe!UIpNetDriver::InitListen(FNetworkNotify * InNotify, FURL & LocalURL, bool bReuseAddressAndPort, FString & Error) Line 152 C++ MyProjectServer.exe!UWorld::Listen(FURL & InURL) Line 3927 C++ MyProjectServer.exe!UEngine::LoadMap(FWorldContext & WorldContext, FURL URL, UPendingNetGame * Pending, FString & Error) Line 8983 C++ MyProjectServer.exe!UEngine::Browse(FWorldContext & WorldContext, FURL URL, FString & Error) Line 8144 C++ MyProjectServer.exe!UGameInstance::StartGameInstance() Line 262 C++ MyProjectServer.exe!UGameEngine::Init(IEngineLoop * InEngineLoop) Line 465 C++ MyProjectServer.exe!FEngineLoop::Init() Line 1967 C++ MyProjectServer.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 138 C++ MyProjectServer.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 191 C++
Open level command
When you execute the "open" command from console, it will queue the travel to open the map:
MyProject2.exe!UGameInstance::HandleOpenCommand(const wchar_t * Cmd, FOutputDevice & Ar, UWorld * InWorld) Line 295 C++ MyProject2.exe!UGameInstance::Exec(UWorld * InWorld, const wchar_t * Cmd, FOutputDevice & Ar) Line 323 C++ MyProject2.exe!UGameViewportClient::Exec(UWorld * InWorld, const wchar_t * Cmd, FOutputDevice & Ar) Line 2014 C++ MyProject2.exe!ULocalPlayer::Exec(UWorld * InWorld, const wchar_t * Cmd, FOutputDevice & Ar) Line 1457 C++ MyProject2.exe!APlayerController::ConsoleCommand(const FString & Cmd, bool bWriteToLog) Line 350 C++ MyProject2.exe!UConsole::ConsoleCommand(const FString & Command) Line 394 C++ MyProject2.exe!UConsole::InputKey_InputLine(int ControllerId, FKey Key, EInputEvent Event, float AmountDepressed, bool bGamepad) Line 651 C++ MyProject2.exe!UConsole::InputKey(int ControllerId, FKey Key, EInputEvent Event, float AmountDepressed, bool bGamepad) Line 1062 C++ MyProject2.exe!UGameViewportClient::InputKey(FViewport * InViewport, int ControllerId, FKey Key, EInputEvent EventType, float AmountDepressed, bool bGamepad) Line 265 C++
Then at the next tick it will do this:
MyProject2.exe!UEngine::Browse(FWorldContext & WorldContext, FURL URL, FString & Error) Line 8161 C++ MyProject2.exe!UEngine::TickWorldTravel(FWorldContext & Context, float DeltaSeconds) Line 8311 C++ MyProject2.exe!UGameEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 812 C++ MyProject2.exe!FEngineLoop::Tick() Line 2257 C++ MyProject2.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 142 C++
Collision Tests
Inside ApsItemActor::ApsItemActor() no special code
Character collides with items
  Inside ApsItemActor::ApsItemActor()
   mesh->SetCollisionProfileName("NoCollision");
   mesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Character does not collide with items
  Inside EntityManager::CreateItem() after SpawnActor
   mesh->SetCollisionProfileName("NoCollision");
   mesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Character collides with items (code seems to have no effect)
Quest interaction sequence
When the player is clicking on the talk icon , this happens, and sends back to the client all the possible quest options:
 APlaneshiftPlayerControllerBase::TalkInteraction()
    ApsCharacter::ShowPopupMenu
       NpcDialogMenu::ShowMenu
          eventManager->SendDialogMenuMessageDelayed
When the player is selecting one option in the npc bubble menu, he sends a chat message to the NPC
  APlaneshiftPlayerControllerBase::SendChatMessage
    ChatManager::HandleChatMessage with type CHAT_NPC
      NpcResponse::ExecuteScript (based on the response found, we execute the script, which may include a number of steps, like say something, do an animation, etc...)
          If there is no delay the ShowMenu is called instantly, otherwise its the client who has to call it when he finished displaying all text (old client was calling /npcmenu from pawsNpcDialogWindow::Draw()