private static void UpdateSub(SubRoot sub) { var gameObject = sub.gameObject; var res = new ClientVehicleMovement(); res.id = Multiplayer.main.self.id; res.vehicleGuid = GuidHelper.Get(gameObject); res.vehicleTech = TechType.Cyclops; res.position = gameObject.transform.position; res.rotation = gameObject.transform.rotation; var rigidbody = sub.GetComponent <Rigidbody>(); if (rigidbody != null) { res.velocity = rigidbody.velocity; res.angularVelocity = rigidbody.angularVelocity; } var subControl = sub.GetComponent <SubControl>(); if (subControl != null) { res.steeringWheelYaw = (float)subControl.ReflectionGet("steeringWheelYaw"); res.steeringWheelPitch = (float)subControl.ReflectionGet("steeringWheelPitch"); res.throttle = subControl.appliedThrottle && (bool)subControl.ReflectionGet("canAccel"); } Multiplayer.main.Send(res, DeliveryMethod.Sequenced); }
/// <summary> /// Send out a <see cref="CyclopsDamage"/> packet /// </summary> private void BroadcastDamageState(SubRoot subRoot, Optional <DamageInfo> info) { string subGuid = GuidHelper.GetGuid(subRoot.gameObject); LiveMixin subHealth = subRoot.gameObject.RequireComponent <LiveMixin>(); if (subHealth.health > 0) { CyclopsDamageInfoData damageInfo = null; if (info.IsPresent()) { DamageInfo damage = info.Get(); // Source of the damage. Used if the damage done to the Cyclops was not calculated on other clients. Currently it's just used to figure out what sounds and // visual effects should be used. CyclopsDamageInfoData serializedDamageInfo = new CyclopsDamageInfoData(subGuid, damage.dealer != null ? GuidHelper.GetGuid(damage.dealer) : string.Empty, damage.originalDamage, damage.damage, damage.position, damage.type); } int[] damagePointIndexes = GetActiveDamagePoints(subRoot).ToArray(); CyclopsFireData[] firePoints = GetActiveRoomFires(subRoot.GetComponent <SubFire>()).ToArray(); CyclopsDamage packet = new CyclopsDamage(subGuid, subRoot.GetComponent <LiveMixin>().health, subRoot.damageManager.subLiveMixin.health, subRoot.GetComponent <SubFire>().liveMixin.health, damagePointIndexes, firePoints, damageInfo); packetSender.Send(packet); } else { // RIP CyclopsDestroyed packet = new CyclopsDestroyed(subGuid); packetSender.Send(packet); } }
public void SetPilotingChair(PilotingChair newPilotingChair) { if (PilotingChair != newPilotingChair) { PilotingChair = newPilotingChair; Validate.NotNull(SubRoot, "Player changed PilotingChair but is not in SubRoot!"); MultiplayerCyclops mpCyclops = SubRoot.GetComponent <MultiplayerCyclops>(); if (PilotingChair != null) { Attach(PilotingChair.sittingPosition.transform); ArmsController.SetWorldIKTarget(PilotingChair.leftHandPlug, PilotingChair.rightHandPlug); mpCyclops.CurrentPlayer = this; mpCyclops.Enter(); } else { SetSubRoot(SubRoot); ArmsController.SetWorldIKTarget(null, null); mpCyclops.CurrentPlayer = null; mpCyclops.Exit(); } RigidBody.isKinematic = AnimationController["cyclops_steering"] = newPilotingChair != null; } }
public void SetPilotingChair(PilotingChair newPilotingChair) { if (activeSub == null) { return; } if (activeChair == newPilotingChair) { return; } activeChair = newPilotingChair; var syncedCyclops = activeSub.GetComponent <SyncedCyclops>(); if (activeChair != null) { Attach(activeChair.sittingPosition.transform); syncedCyclops.Enter(this); // arms.SetWorldIKTarget(activeChair.leftHandPlug, activeChair.rightHandPlug); } else { SetSubRoot(activeSub); syncedCyclops.Exit(); // arms.SetWorldIKTarget(null, null); } var steering = (newPilotingChair != null); animator.main.SetBool("cyclops_steering", steering); // rigidbody.isKinematic = steering; }
public static void OnProtoDeserialize_Postfix(SubRoot __instance, ProtobufSerializer serializer) { // Get base/cyclops prefab ID var prefabId = __instance.GetComponent <PrefabIdentifier>(); if (prefabId == null) { return; // Return if we were not able to get unique prefab ID } // Get save folder path string saveFolderPath = Path.Combine(Path.Combine(@"./SNAppData/SavedGames/", SaveLoadManager.main.GetCurrentSlot()), "BaseLightSwitch"); if (!Directory.Exists(saveFolderPath)) { return; // Return if save folder does not exist } // Get save file path string saveFilePath = Path.Combine(saveFolderPath, "lightsstate_" + prefabId.Id + ".txt"); if (!File.Exists(saveFilePath)) { return; // Return if there's no data saved for this base/cyclops } // Get base/cyclops saved lights state string savedData = File.ReadAllText(saveFilePath, Encoding.UTF8); bool savedLightsState = (string.IsNullOrEmpty(savedData) || savedData != "0"); // Attach a small component that will restore base/cyclops lights state __instance.gameObject.AddComponent <SubRootRestoreLightsState>().IsLightsOn = savedLightsState; }
public static void OnProtoSerialize_Postfix(SubRoot __instance, ProtobufSerializer serializer) { // Get base/cyclops prefab ID var prefabId = __instance.GetComponent <PrefabIdentifier>(); if (prefabId == null) { return; // Return if we were not able to get or set unique prefab ID } // Prepare save path string saveFolderPath = Path.Combine(Path.Combine(@"./SNAppData/SavedGames/", SaveLoadManager.main.GetCurrentSlot()), "BaseLightSwitch"); if (!Directory.Exists(saveFolderPath)) { Directory.CreateDirectory(saveFolderPath); } // Get base/cyclops lights state FieldInfo isLightsOnField = typeof(SubRoot).GetField("subLightsOn", BindingFlags.Instance | BindingFlags.NonPublic); bool isLightsOn = (bool)isLightsOnField.GetValue(__instance); // Save base/cyclops lights state File.WriteAllText(Path.Combine(saveFolderPath, "lightsstate_" + prefabId.Id + ".txt"), isLightsOn ? "1" : "0", Encoding.UTF8); }
public void UpdateVehiclePosition(VehicleMovementData vehicleModel, Optional <RemotePlayer> player) { Vector3 remotePosition = vehicleModel.Position; Vector3 remoteVelocity = vehicleModel.Velocity; Quaternion remoteRotation = vehicleModel.Rotation; Vector3 angularVelocity = vehicleModel.AngularVelocity; Vehicle vehicle = null; SubRoot subRoot = null; Optional <GameObject> opGameObject = NitroxEntity.GetObjectFrom(vehicleModel.Id); if (opGameObject.HasValue) { GameObject gameObject = opGameObject.Value; vehicle = gameObject.GetComponent <Vehicle>(); subRoot = gameObject.GetComponent <SubRoot>(); MultiplayerVehicleControl mvc = null; if (subRoot != null) { mvc = subRoot.gameObject.EnsureComponent <MultiplayerCyclops>(); subRoot.GetComponent <LiveMixin>().health = vehicleModel.Health; } else if (vehicle != null) { SeaMoth seamoth = vehicle as SeaMoth; Exosuit exosuit = vehicle as Exosuit; if (seamoth) { mvc = seamoth.gameObject.EnsureComponent <MultiplayerSeaMoth>(); } else if (exosuit) { mvc = exosuit.gameObject.EnsureComponent <MultiplayerExosuit>(); if (vehicleModel.GetType() == typeof(ExosuitMovementData)) { ExosuitMovementData exoSuitMovement = (ExosuitMovementData)vehicleModel; mvc.SetArmPositions(exoSuitMovement.LeftAimTarget, exoSuitMovement.RightAimTarget); } else { Log.Error($"{nameof(Vehicles)}: Got exosuit vehicle but no ExosuitMovementData"); } } vehicle.GetComponent <LiveMixin>().health = vehicleModel.Health; } if (mvc != null) { mvc.SetPositionVelocityRotation(remotePosition, remoteVelocity, remoteRotation, angularVelocity); mvc.SetThrottle(vehicleModel.AppliedThrottle); mvc.SetSteeringWheel(vehicleModel.SteeringWheelYaw, vehicleModel.SteeringWheelPitch); } } if (player.HasValue) { RemotePlayer playerInstance = player.Value; playerInstance.SetVehicle(vehicle); playerInstance.SetSubRoot(subRoot); playerInstance.SetPilotingChair(subRoot?.GetComponentInChildren <PilotingChair>()); playerInstance.AnimationController.UpdatePlayerAnimations = false; } }
private Optional<VehicleMovementData> GetVehicleMovement() { Vehicle vehicle = Player.main.GetVehicle(); SubRoot sub = Player.main.GetCurrentSub(); NitroxId id; Vector3 position; Quaternion rotation; Vector3 velocity; Vector3 angularVelocity; TechType techType; float steeringWheelYaw = 0f, steeringWheelPitch = 0f; bool appliedThrottle = false; Vector3 leftArmPosition = new Vector3(0, 0, 0); Vector3 rightArmPosition = new Vector3(0, 0, 0); if (vehicle != null) { id = NitroxEntity.GetId(vehicle.gameObject); position = vehicle.gameObject.transform.position; rotation = vehicle.gameObject.transform.rotation; techType = CraftData.GetTechType(vehicle.gameObject); Rigidbody rigidbody = vehicle.gameObject.GetComponent<Rigidbody>(); velocity = rigidbody.velocity; angularVelocity = rigidbody.angularVelocity; // Required because vehicle is either a SeaMoth or an Exosuit, both types which can't see the fields either. steeringWheelYaw = (float)vehicle.ReflectionGet<Vehicle, Vehicle>("steeringWheelYaw"); steeringWheelPitch = (float)vehicle.ReflectionGet<Vehicle, Vehicle>("steeringWheelPitch"); // Vehicles (or the SeaMoth at least) do not have special throttle animations. Instead, these animations are always playing because the player can't even see them (unlike the cyclops which has cameras). // So, we need to hack in and try to figure out when thrust needs to be applied. if (vehicle && AvatarInputHandler.main.IsEnabled()) { if (techType == TechType.Seamoth) { bool flag = vehicle.transform.position.y < Ocean.main.GetOceanLevel() && vehicle.transform.position.y < vehicle.worldForces.waterDepth && !vehicle.precursorOutOfWater; appliedThrottle = flag && GameInput.GetMoveDirection().sqrMagnitude > .1f; } else if (techType == TechType.Exosuit) { Exosuit exosuit = vehicle as Exosuit; if (exosuit) { appliedThrottle = (bool)exosuit.ReflectionGet("_jetsActive") && (float)exosuit.ReflectionGet("thrustPower") > 0f; Transform leftAim = (Transform)exosuit.ReflectionGet("aimTargetLeft", true); Transform rightAim = (Transform)exosuit.ReflectionGet("aimTargetRight", true); Vector3 eulerAngles = exosuit.transform.eulerAngles; eulerAngles.x = MainCamera.camera.transform.eulerAngles.x; Quaternion quaternion = Quaternion.Euler(eulerAngles.x, eulerAngles.y, eulerAngles.z); leftArmPosition = leftAim.transform.position = MainCamera.camera.transform.position + quaternion * Vector3.forward * 100f; rightArmPosition = rightAim.transform.position = MainCamera.camera.transform.position + quaternion * Vector3.forward * 100f; } } } } else if (sub != null && Player.main.isPiloting) { id = NitroxEntity.GetId(sub.gameObject); position = sub.gameObject.transform.position; rotation = sub.gameObject.transform.rotation; Rigidbody rigidbody = sub.GetComponent<Rigidbody>(); velocity = rigidbody.velocity; angularVelocity = rigidbody.angularVelocity; techType = TechType.Cyclops; SubControl subControl = sub.GetComponent<SubControl>(); steeringWheelYaw = (float)subControl.ReflectionGet("steeringWheelYaw"); steeringWheelPitch = (float)subControl.ReflectionGet("steeringWheelPitch"); appliedThrottle = subControl.appliedThrottle && (bool)subControl.ReflectionGet("canAccel"); } else { return Optional.Empty; } VehicleMovementData model = VehicleMovementFactory.GetVehicleMovementData(techType, id, position, rotation, velocity, angularVelocity, steeringWheelYaw, steeringWheelPitch, appliedThrottle, leftArmPosition, rightArmPosition); return Optional.Of(model); }
private Optional <VehicleModel> GetVehicleModel() { Vehicle vehicle = Player.main.GetVehicle(); SubRoot sub = Player.main.GetCurrentSub(); string guid; Vector3 position; Quaternion rotation; Vector3 velocity; Vector3 angularVelocity; TechType techType; float steeringWheelYaw = 0f, steeringWheelPitch = 0f; bool appliedThrottle = false; if (vehicle != null) { guid = GuidHelper.GetGuid(vehicle.gameObject); position = vehicle.gameObject.transform.position; rotation = vehicle.gameObject.transform.rotation; techType = CraftData.GetTechType(vehicle.gameObject); Rigidbody rigidbody = vehicle.gameObject.GetComponent <Rigidbody>(); velocity = rigidbody.velocity; angularVelocity = rigidbody.angularVelocity; // Required because vehicle is either a SeaMoth or an Exosuit, both types which can't see the fields either. steeringWheelYaw = (float)vehicle.ReflectionGet <Vehicle, Vehicle>("steeringWheelYaw"); steeringWheelPitch = (float)vehicle.ReflectionGet <Vehicle, Vehicle>("steeringWheelPitch"); // Vehicles (or the SeaMoth at least) do not have special throttle animations. Instead, these animations are always playing because the player can't even see them (unlike the cyclops which has cameras). // So, we need to hack in and try to figure out when thrust needs to be applied. if (vehicle && AvatarInputHandler.main.IsEnabled()) { if (techType == TechType.Seamoth) { bool flag = vehicle.transform.position.y < Ocean.main.GetOceanLevel() && vehicle.transform.position.y < vehicle.worldForces.waterDepth && !vehicle.precursorOutOfWater; appliedThrottle = flag && GameInput.GetMoveDirection().sqrMagnitude > .1f; } else if (techType == TechType.Exosuit) { Exosuit exosuit = vehicle as Exosuit; if (exosuit) { appliedThrottle = (bool)exosuit.ReflectionGet("_jetsActive") && (float)exosuit.ReflectionGet("thrustPower") > 0f; } } } } else if (sub != null && Player.main.isPiloting) { guid = GuidHelper.GetGuid(sub.gameObject); position = sub.gameObject.transform.position; rotation = sub.gameObject.transform.rotation; Rigidbody rigidbody = sub.GetComponent <Rigidbody>(); velocity = rigidbody.velocity; angularVelocity = rigidbody.angularVelocity; techType = TechType.Cyclops; SubControl subControl = sub.GetComponent <SubControl>(); steeringWheelYaw = (float)subControl.ReflectionGet("steeringWheelYaw"); steeringWheelPitch = (float)subControl.ReflectionGet("steeringWheelPitch"); appliedThrottle = subControl.appliedThrottle && (bool)subControl.ReflectionGet("canAccel"); } else { return(Optional <VehicleModel> .Empty()); } VehicleModel model = new VehicleModel(techType, guid, position, rotation, velocity, angularVelocity, steeringWheelYaw, steeringWheelPitch, appliedThrottle); return(Optional <VehicleModel> .Of(model)); }