/** 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; } }