private void ServerTimerTickCallback() { var time = Server.Game.FrameTime; serverRequests.ProcessAndRemoveByPair( pair => { // process unstuck var character = pair.Key; var request = pair.Value; if (character.GetPublicState <ICharacterPublicState>() .IsDead) { // character is dead this.CallClient(character, _ => _.ClientRemote_UnstuckFailedDead()); return(true); // remove this request } if (request.InitialPosition.DistanceSquaredTo(character.Position) > MaxUnstuckMovementDistance * MaxUnstuckMovementDistance) { // character moved ServerNotifyUnstuckCancelledCharacterMoved(character); return(true); // remove this request } if (!SharedValidateCanUnstuck(character)) { return(true); // remove this request } if (request.UnstuckAfter > time) { // time is not expired yet return(false); // don't remove this request } // try to teleport player away but nearby if (!CharacterRespawnSystem.ServerTryPlaceCharacterNearby(character, character.Position)) { // try to simply respawn in starting area (only the character position will be changed) ServerPlayerSpawnManager.PlacePlayer(character, isRespawn: false); } Logger.Info( $"Character unstuck from {request.InitialPosition} to {character.TilePosition}", character); this.CallClient(character, _ => _.ClientRemote_UnstuckSuccessful()); return(true); // remove this request }, removeCallback: pair => { var character = pair.Key; ServerOnUnstuckRequestRemoved(character); }); }
private void ServerTimerTickCallback() { var time = Server.Game.FrameTime; serverRequests.ProcessAndRemoveByPair( pair => { // process unstuck var character = pair.Key; var request = pair.Value; if (character.GetPublicState <ICharacterPublicState>() .IsDead) { // character is dead this.CallClient(character, _ => _.ClientRemote_UnstuckFailedDead()); return(true); // remove this request } if (request.InitialPosition.DistanceSquaredTo(character.Position) > MaxUnstuckMovementDistance * MaxUnstuckMovementDistance) { // character moved this.CallClient(character, _ => _.ClientRemote_UnstuckFailedCharacterMoved()); return(true); // remove this request } if (request.UnstuckAfter > time) { // time is not expired yet return(false); // don't remove this request } // it's like respawn but we only change the character position ServerPlayerSpawnManager.PlacePlayer(character, isRespawn: false); Logger.Info( $"Character unstuck from {request.InitialPosition} to {character.TilePosition}", character); this.CallClient(character, _ => _.ClientRemote_UnstuckSuccessful()); return(true); // remove this request }, removeCallback: pair => { }); }