/** Sets the current ball possessor */
void AMagicBattleSoccerBall::SetPossessor(AMagicBattleSoccerCharacter* Player)
{
    if (Role < ROLE_Authority)
    {
        // Safety check. Only authority entities should drive the ball.
    }
    else
    {
        // We only allow a possession change if the ball is being unpossessed or the player is not one we're ignoring
        if (nullptr == Player || (CanPossessBall(Player) && (PossessorToIgnore != Player)))
        {
            AMagicBattleSoccerCharacter *OldPossessor = Possessor;

            // Assign the new possessor
            Possessor = Player;

            // Handle cases when the ball had a possessor in the previous frame
            if (nullptr != OldPossessor)
            {
                // Assign the last possessor
                LastPossessor = OldPossessor;
                // Assign the possessor to ignore
                PossessorToIgnore = OldPossessor;
            }

            // Toggle physics
            UPrimitiveComponent *Root = Cast<UPrimitiveComponent>(GetRootComponent());
            if (nullptr != Possessor)
            {
                Possessor->StopWeaponFire(Possessor->PrimaryWeapon);
                Possessor->StopWeaponFire(Possessor->SecondaryWeapon);
                Root->PutRigidBodyToSleep();
                Root->SetSimulatePhysics(false);
                Root->SetEnableGravity(false);
                SetActorEnableCollision(false);
                MoveWithPossessor();
            }
            else
            {
                Root->SetSimulatePhysics(true);
                Root->SetEnableGravity(true);
                SetActorEnableCollision(true);
                Root->PutRigidBodyToSleep();
            }
        }

        // Force the orientation to be replicated at the same time the possessor is replicated
        UPrimitiveComponent *Root = Cast<UPrimitiveComponent>(GetRootComponent());
        ServerPhysicsState.pos = GetActorLocation();
        ServerPhysicsState.rot = GetActorRotation();
        ServerPhysicsState.vel = Root->GetComponentVelocity();
        ServerPhysicsState.timestamp = AMagicBattleSoccerPlayerController::GetLocalTime();
    }
}
/** This occurs when play begins */
void AMagicBattleSoccerBall::BeginPlay()
{
    Super::BeginPlay();

    if (Role < ROLE_Authority)
    {
        // The server manages the game state; the soccer ball will be replicated to us.

        // Physics however are not replicated. We will need to have the ball orientation
        // replicated to us. We need to turn off physics simulation and collision detection.
        UPrimitiveComponent *Root = Cast<UPrimitiveComponent>(GetRootComponent());
        Root->PutRigidBodyToSleep();
        Root->SetSimulatePhysics(false);
        Root->SetEnableGravity(false);
        SetActorEnableCollision(false);
    }
    else
    {
        // Servers should add this soccer ball to the game mode cache.
        // It will get replicated to clients for when they need to access
        // the ball itself to get information such as who possesses it.
        AMagicBattleSoccerGameState* GameState = GetGameState();
        GameState->SoccerBall = this;
    }
}
/** Called by the GameMode object when the next round has begun */
void AMagicBattleSoccerBall::RoundHasStarted_Implementation()
{
    if (Role == ROLE_Authority)
    {
        if (nullptr != Possessor)
        {
            SetPossessor(nullptr); // This change will be replicated to all clients
        }
        else
        {
            UPrimitiveComponent *Root = Cast<UPrimitiveComponent>(GetRootComponent());
            Root->PutRigidBodyToSleep();
        }
        PossessorToIgnore = nullptr;
    }
}