/// <summary> /// Update the position of a player with the given position. /// </summary> /// <param name="id">The ID of the player.</param> /// <param name="position">The new position of the player.</param> public void UpdatePosition(ushort id, Vector2 position) { if (!_playerData.TryGetValue(id, out var playerData) || !playerData.IsInLocalScene) { // Logger.Get().Warn(this, $"Tried to update position for ID {id} while player data did not exists"); return; } var playerContainer = playerData.PlayerContainer; if (playerContainer != null) { var unityPosition = new Vector3(position.X, position.Y); playerContainer.GetComponent <PositionInterpolation>().SetNewPosition(unityPosition); } }
/// <summary> /// Create a map icon for a player. /// </summary> /// <param name="id">The ID of the player.</param> /// <param name="position">The position of the map icon.</param> private void CreatePlayerIcon(ushort id, Vector2 position) { var gameMap = GetGameMap(); if (gameMap == null) { return; } var compassIconPrefab = gameMap.compassIcon; if (compassIconPrefab == null) { Logger.Get().Error(this, "CompassIcon prefab is null"); return; } // Create a new player icon relative to the game map var mapIcon = Object.Instantiate( compassIconPrefab, gameMap.gameObject.transform ); mapIcon.SetActive(_displayingIcons); // Subtract ID * 0.01 from the Z position to prevent Z-fighting with the icons var unityPosition = new Vector3( position.X, position.Y, id * -0.01f ); // Set the position of the player icon mapIcon.transform.localPosition = unityPosition; // Remove the bob effect when walking with the map Object.Destroy(mapIcon.LocateMyFSM("Mapwalk Bob")); // Put it in the list _mapIcons[id] = mapIcon; }
public void UpdatePosition(Vector2 position) { var unityPos = new Vector3(position.X, position.Y); GameObject.GetComponent <PositionInterpolation>().SetNewPosition(unityPos); }
/// <summary> /// Spawn a new player object with the given data. /// </summary> /// <param name="playerData">The client player data for the player.</param> /// <param name="name">The username of the player.</param> /// <param name="position">The Vector2 denoting the position of the player.</param> /// <param name="scale">The boolean representing the scale of the player.</param> /// <param name="team">The team the player is on.</param> /// <param name="skinId">The ID of the skin the player is using.</param> public void SpawnPlayer( ClientPlayerData playerData, string name, Vector2 position, bool scale, Team team, byte skinId ) { GameObject playerContainer; if (_inactivePlayers.Count <= 0) { // Create a new player container playerContainer = Object.Instantiate(_playerContainerPrefab); Object.DontDestroyOnLoad(playerContainer); } else { // Dequeue a player container from the inactive players playerContainer = _inactivePlayers.Dequeue(); } playerContainer.name = $"Player Container {playerData.Id}"; _activePlayers[playerData.Id] = playerContainer; playerContainer.transform.SetPosition2D(position.X, position.Y); var playerObject = playerContainer.FindGameObjectInChildren("PlayerPrefab"); SetPlayerObjectBoolScale(playerObject, scale); // Set container and children active playerContainer.SetActive(true); playerContainer.SetActiveChildren(true); // Disable DamageHero component unless pvp is enabled if (_gameSettings.IsPvpEnabled && _gameSettings.IsBodyDamageEnabled) { playerObject.layer = 11; playerObject.GetComponent <DamageHero>().enabled = true; } else { playerObject.layer = 9; playerObject.GetComponent <DamageHero>().enabled = false; } AddNameToPlayer(playerContainer, name, team); // Let the SkinManager update the skin _skinManager.UpdatePlayerSkin(playerObject, skinId); // Store the player data playerData.PlayerContainer = playerContainer; playerData.PlayerObject = playerObject; playerData.Team = team; playerData.SkinId = skinId; // Set whether this player should have body damage // Only if: // PvP is enabled and body damage is enabled AND // (the teams are not equal or if either doesn't have a team) ToggleBodyDamage( playerData, _gameSettings.IsPvpEnabled && _gameSettings.IsBodyDamageEnabled && (team != LocalPlayerTeam || team.Equals(Team.None) || LocalPlayerTeam.Equals(Team.None)) ); }
/// <summary> /// Callback method on the HeroController#Update method. /// </summary> /// <param name="orig">The original method.</param> /// <param name="self">The HeroController instance.</param> private void OnPlayerUpdate(On.HeroController.orig_Update orig, HeroController self) { // Make sure the original method executes orig(self); // Ignore player position updates on non-gameplay scenes var currentSceneName = SceneUtil.GetCurrentSceneName(); if (SceneUtil.IsNonGameplayScene(currentSceneName)) { return; } // If we are not connected, there is nothing to send to if (!_netClient.IsConnected) { return; } var heroTransform = HeroController.instance.transform; var newPosition = heroTransform.position; // If the position changed since last check if (newPosition != _lastPosition) { // Update the last position, since it changed _lastPosition = newPosition; if (_sceneChanged) { _sceneChanged = false; // Set some default values for the packet variables in case we don't have a HeroController instance // This might happen when we are in a non-gameplay scene without the knight var position = Vector2.Zero; var scale = Vector3.zero; ushort animationClipId = 0; // If we do have a HeroController instance, use its values if (HeroController.instance != null) { var transform = HeroController.instance.transform; var transformPos = transform.position; position = new Vector2(transformPos.x, transformPos.y); scale = transform.localScale; animationClipId = (ushort)AnimationManager.GetCurrentAnimationClip(); } Logger.Get().Info(this, "Sending EnterScene packet"); _netClient.UpdateManager.SetEnterSceneData( SceneUtil.GetCurrentSceneName(), position, scale.x > 0, animationClipId ); } else { // If this was not the first position update after a scene change, // we can simply send a position update packet _netClient.UpdateManager.UpdatePlayerPosition(new Vector2(newPosition.x, newPosition.y)); } } var newScale = heroTransform.localScale; // If the scale changed since last check if (newScale != _lastScale) { _netClient.UpdateManager.UpdatePlayerScale(newScale.x > 0); // Update the last scale, since it changed _lastScale = newScale; } }
/// <summary> /// Callback method for the HeroController#Update method. /// </summary> /// <param name="orig">The original method.</param> /// <param name="self">The HeroController instance.</param> private void HeroControllerOnUpdate(On.HeroController.orig_Update orig, HeroController self) { // Execute the original method orig(self); // If we are not connect, we don't have to send anything if (!_netClient.IsConnected) { return; } var sendEmptyUpdate = false; if (!_gameSettings.AlwaysShowMapIcons) { if (!_gameSettings.OnlyBroadcastMapIconWithWaywardCompass) { sendEmptyUpdate = true; } else { // We do not always show map icons, but only when we are wearing wayward compass // So we need to check whether we are wearing wayward compass if (!PlayerData.instance.GetBool(nameof(PlayerData.equippedCharm_2))) { sendEmptyUpdate = true; } } } if (sendEmptyUpdate) { if (_lastSentEmptyUpdate) { return; } _netClient.UpdateManager.UpdatePlayerMapPosition(Vector2.Zero); // Set the last position to zero, so that when we // equip it again, we immediately send the update since the position changed _lastPosition = Vector3.zero; _lastSentEmptyUpdate = true; return; } var newPosition = GetMapLocation(); // Only send update if the position changed if (newPosition != _lastPosition) { var vec2 = new Vector2(newPosition.x, newPosition.y); _netClient.UpdateManager.UpdatePlayerMapPosition(vec2); // Update the last position, since it changed _lastPosition = newPosition; _lastSentEmptyUpdate = false; } }