커버의 Path Build

커버에서는 slip, mantle, swatturn, 등의 다양한 액션을 취할 수 있다. 하지만 설치된 커버와 주변 환경과의 이해관계에 따라 이 중에서 수행하지 못하는 액션도 있을 것이다.

예를 들어 높은 장애물에서는 mantle 을 하지 못할 것이고 장애물의 가장자리가 아니라면 slip 이나 swatturn 의 행동을 할 수 없을 것이다.

GoW3 에서는 이런 액션의 가능 여부를 실시간으로 계산하는 것이 아니라 에디터에서 미리 계산하여 해당 커버에 플래그 형태로 저장해 둔다.1)

그리고 런타임에는 이 플래그를 조회하여 현재 커버에서 수행할 수 있는 액션들을 가려낸다.

에디터에서 커버를 빌드하는 방법은 크게 두가지가 있는데

  • 상단에 위치한 PathBuild 버튼을 클릭했을 경우
    • WxEditorFrame::MeshBuild → FEditorBuildUtils::EditorBuild
    • FPathBuilder::BuildPaths → FPathBuild::Exec
    • AGearScout::Exec → AScout::Exec
    • AScout::BuildCover
    • ACoverLink::BuildSlotInfo → ACoverLink::BuildSlotInfoInternal
  • 마우스 Middle 버튼을 클릭했을 경우
    • FEditorModeTools::InputKey
    • FEdModeCoverEdit::InputKey
    • ACoverLink::BuildSlotInfo → ACoverLink::BuildSlotInfoInternal

두가지 경우 모두 ACoverLink::BuildSlotInfoInternal 함수로 들어오는데

UnCover.cpp
void ACoverLink::BuildSlotInfoInternal( ... )
{
    ...
    if ( Slot.bCanMantle )
    {
        Slot.bCanMantle = Scout->CanDoMove( TEXT("MANTLE"), this, SlotIdx, bSeedPylon );   // Scout 에게 mantle 액션 가능여부 판별토록 위임.
    }
 
    // 이하 다른 액션들도 마찬가지
    ...
}

위와 같이 Scout 에게 위임한다. 이어서 GearScout 를 보면

GearPath.cpp
UBOOL AGearScout::CanDoMove( ... )
{
    ...
    ACoverLink* Link = Cast<ACoverLink>( Nav );
    if ( ParseCommand( &Str, TEXT("MANTLE") ) )
    {
        ...
        return CanMantle( SlotLocation, SlotRotation, 0, Link );   // mantle 여부 체크
    }
    ...
}
 
UBOOL AGearScout::CanMantle( ... )
{
    ... // 블라블라
}

이런 식으로 되어 있다.

1) CoverLink.uc 에 CoverSlot 구조체 참조