public virtual void Initialise(ref Hoverbike vehicle) { parentHoverbike = vehicle; //defaultWaterDampening = vehicle.waterDampening; //defaultWaterOffset = vehicle.waterLevelOffset; foreach (HoverbikeField hoverbikeField in hoverbikeFields) { FieldInfo field = typeof(Hoverbike).GetField(hoverbikeField.fieldName, hoverbikeField.bindingFlags); if (field != null) { if (defaultValues.ContainsKey(hoverbikeField.fieldName)) { Log.LogError($"Tried to add key {hoverbikeField.fieldName} more than once!"); } else { defaultValues.Add(hoverbikeField.fieldName, (float)field.GetValue(vehicle)); Log.LogDebug($"HoverbikeUpdate.Initialise(): Got default value of {defaultValues[hoverbikeField.fieldName]} for field name {hoverbikeField.fieldName}"); } } else { Log.LogDebug($"Could not find field {hoverbikeField.fieldName} in class Hoverbike"); } } }
private static bool Prefix(Hoverbike __instance) { if (MainPatch.snowfoxIsDocked == true) { if (__instance.toggleLights.enabled == true) { MainPatch.state.HoveBikeLightState = true; Config.ToggleValue = true; ConfigFile.AttemptToSave(MainPatch.state.HoveBikeLightState); __instance.toggleLights.enabled = false; } } else { if (MainPatch.state.HoveBikeLightState == true) { //Debug.Log($"Hoverbike Lights link not working hoveBikeLight is {hoverbikeLight}"); if (__instance.transform.Find("Deployed").transform.Find("Lights") != false) { Debug.Log("It found the lights"); var hoverbikeLight = __instance.transform.Find("Deployed").transform.Find("Lights").GetComponentsInChildren <Light>(false); Debug.Log("[Speedo] 1"); MainPatch.state.HoveBikeLightState = false; Config.ToggleValue = false; ConfigFile.AttemptToSave(MainPatch.state.HoveBikeLightState); if (hoverbikeLight != null) { foreach (var light in hoverbikeLight) { if (light.gameObject.name.Contains("Light_Main") != false) { if (light.gameObject.name.Contains("x_FakeVolumletricLight") != false) { Debug.Log("[Speedo] 2"); __instance.toggleLights.enabled = true; } else { Debug.Log("[Speedo] 3 x_FakeVolumletricLight is false"); } } else { Debug.Log("[Speedo] 3 Light_Main is false"); //__instance.toggleLights.enabled = true; //__instance.toggleLights.lightsActive = true; } } } } else { Debug.Log("Hoverbike Lights link not working"); } } } return(true); }
internal bool HasTravelModule(Hoverbike instance = null) { if (instance != null) { return(StaticHasTravelModule(instance)); } return(StaticHasTravelModule(parentHoverbike)); }
protected static int StaticGetModuleCount(TechType techType, Hoverbike instance = null) { if (instance == null) { return(0); } return(instance.modules.GetCount(techType)); }
internal static bool StaticHasTravelModule(Hoverbike instance) { if (instance == null) { return(false); } return((StaticGetModuleCount(techTypeMobility, instance) + StaticGetModuleCount(techTypeWaterTravel, instance)) > 0); }
public void Awake() { hoverbike = GetComponent <Hoverbike>(); modules = hoverbike.modules; BZLogger.Debug("WaterRideManager", "Adding slot listener handlers..."); modules.onEquip += OnEquip; modules.onUnequip += OnUnEquip; }
protected virtual int GetModuleCount(TechType techType, Hoverbike instance = null) { if (instance != null) { return(instance.modules.GetCount(techType)); } if (parentHoverbike == null || parentHoverbike.modules == null) { return(0); } return(parentHoverbike.modules.GetCount(techType)); }
internal virtual void PostHoverEngines(Hoverbike instance = null) { if (parentHoverbike == null) { if (instance != null) { Initialise(ref instance); } else { return; } } }
internal void PrintForces(Hoverbike hoverbike) { BZLogger.Log($"[{CmZConfig.PROGRAM_NAME}] DebugHoverBike:\n" + $"forwardAccel: {hoverbike.forwardAccel}\n" + $"forwardBoostForce: {hoverbike.forwardBoostForce}\n" + $"fovMaxVelocity: {hoverbike.fovMaxVelocity}\n" + $"fovSmoothSpeed: {hoverbike.fovSmoothSpeed}\n" + $"fovSpeedPower: {hoverbike.fovSpeedPower}\n" + $"verticalBoostForce: {hoverbike.verticalBoostForce}\n" + $"hoverForce: {hoverbike.hoverForce}\n" + $"verticalDampening: { hoverbike.verticalDampening}\n" + $"waterDampening: {hoverbike.waterDampening}\n" + $"waterLevelOffset: {hoverbike.waterLevelOffset}"); }
public static bool WaterHoverMode(Hoverbike instance) { // This method is called in Hoverbike.HoverEngines(), made so via transpiler, and is only called once the code has already established that the Hoverbike is over water. // Also, since we want to fool the game into thinking the hoverbike is not over water if a valid travel module is installed, we need to invert the boolean. // This is because the return result of this method is assigned to the hoverbike's "over water" field; if we want the hoverbike to believe it is over land and thus is allowed // to boost and jump, we have to say "No, you're not over water" if a travel module is present. if (instance?.gameObject == null) { return(true); } return(!HoverbikeUpdater.StaticHasTravelModule(instance)); //instance.modules.GetCount(Main.prefabHbWaterTravelModule.TechType) < 1; }
internal void PrintForces(Hoverbike hoverbike) { Debug.Log($"[CheatManagerZero] DebugHoverBike:\n" + $"forwardAccel: {hoverbike.forwardAccel}\n" + $"forwardBoostForce: {hoverbike.forwardBoostForce}\n" + $"fovMaxVelocity: {hoverbike.fovMaxVelocity}\n" + $"fovSmoothSpeed: {hoverbike.fovSmoothSpeed}\n" + $"fovSpeedPower: {hoverbike.fovSpeedPower}\n" + $"verticalBoostForce: {hoverbike.verticalBoostForce}\n" + $"hoverForce: {hoverbike.hoverForce}\n" + $"verticalDampening: { hoverbike.verticalDampening}\n" + $"waterDampening: {hoverbike.waterDampening}\n" + $"waterLevelOffset: {hoverbike.waterLevelOffset}"); }
public static void PostStart(Hoverbike __instance) { HoverbikeUpdater component = __instance.gameObject.EnsureComponent <HoverbikeUpdater>(); component.Initialise(ref __instance); if (__instance.gameObject != null && __instance.gameObject.TryGetComponent <LiveMixin>(out LiveMixin mixin) && Main.defaultHealth.TryGetValue(TechType.Hoverbike, out float defaultHealth)) { float instanceHealthPct = Mathf.Min(mixin.GetHealthFraction(), 1f); float maxHealth = defaultHealth * Main.config.HoverbikeHealthMult; mixin.data.maxHealth = maxHealth; mixin.health = maxHealth * instanceHealthPct; } }
internal virtual void PostUpdateEnergy(Hoverbike instance = null) { if (parentHoverbike == null) { if (instance != null) { Initialise(ref instance); } else { return; } } if (parentHoverbike.GetPilotingCraft() && bBikeOverWater) { parentHoverbike.energyMixin.ConsumeEnergy(Time.deltaTime * parentHoverbike.enginePowerConsumption); // This effectively doubles power consumption when above water. } }
internal bool WaterHoverMode(Hoverbike instance = null) { // This method is only called if Hoverbike.HoverEngines() has already determined that the hoverbike is above water. // So we basically just need to return whether or not the Water Travel Module is installed. // We need to invert it though, as if the value is true, the code restricts the hoverbike's movement. if (parentHoverbike == null) { if (instance != null) { parentHoverbike = instance; } else { return(false); } } return(HasTravelModule()); }
internal virtual void PreUpdateEnergy(Hoverbike instance = null) { float deltaTime = Time.deltaTime; if (parentHoverbike == null) { if (instance != null) { parentHoverbike = instance; } else { return; } } if (GetModuleCount(techTypeSolarCharger) > 0) { //if (Main.bVerboseLogging) // Log.LogDebug("Solar charger found in Hoverbike"); DayNightCycle dayNightCycle = DayNightCycle.main; if (dayNightCycle == null) { return; } float depthMultiplier = Mathf.Clamp01((fMaxSolarDepth + parentHoverbike.transform.position.y) / fMaxSolarDepth); float lightScalar = dayNightCycle.GetLocalLightScalar(); //Log.LogDebug($"Charging Hoverbike battery with depthMultiplier of {depthMultiplier}, lightScalar = {lightScalar}, fSolarChargeMultiplier = {fSolarChargeMultiplier}, and deltaTime of {deltaTime}"); parentHoverbike.energyMixin.AddEnergy(deltaTime * fSolarChargeMultiplier * depthMultiplier * lightScalar); } if (bHasSelfRepair) { if (parentHoverbike.liveMixin.GetHealthFraction() < 1f && parentHoverbike.energyMixin.GetEnergyScalar() > SelfRepairDisableThreshold) { parentHoverbike.energyMixin.ConsumeEnergy(SelfRepairEnergyConsumption * deltaTime); parentHoverbike.liveMixin.AddHealth(SelfRepairRate * deltaTime); } } }
public static bool PreGetHUDValues(Hoverbike __instance, out float health, out float power) { if (!Main.config.bHUDAbsoluteValues) { health = 0f; power = 0f; return(true); } // The HUD code is expecting values between 0.0 and 1.0 and thus multiplies both of these values by 100 before displaying them. // Easiest way for us to sort this out is to divide the values by 100 first. Less-efficient, but if the player is running on a CPU // where a division by 100 takes a significant chunk of CPU time, they probably can't play Subnautica anyway. health = Mathf.Floor(__instance.liveMixin.health) * 0.01f; float charge = __instance.energyMixin.charge; float capacity = __instance.energyMixin.capacity; //power = ((charge > 0f && capacity > 0f) ? (charge / capacity) : 0f); power = Mathf.Floor(charge) * 0.01f; return(false); }
internal virtual void PrePhysicsMove(Hoverbike instance = null) { if (parentHoverbike == null) { if (instance != null) { Initialise(ref instance); } else { return; } } bBikeOverWater = !parentHoverbike.debugIgnoreWater && instance.transform.position.y < parentHoverbike.waterLevelOffset + 3f; if (bHasTravelModule) { if (parentHoverbike.GetPilotingCraft()) { parentHoverbike.waterLevelOffset = moduleWaterOffset; // Makes the bike hover above the surface when piloted with the Water Travel Module parentHoverbike.waterDampening = moduleWaterDampening; return; } } if (TryGetDefaultFloat("waterOffset", out float defaultWaterOffset)) { parentHoverbike.waterLevelOffset = defaultWaterOffset; // Let the hoverbike sink to water level when not piloted. // Otherwise it can be kind of hard to get on if the water offset is too high. // Of course this also runs if the module isn't installed. } if (TryGetDefaultFloat("waterDampening", out float defaultWaterDampening)) { parentHoverbike.waterDampening = defaultWaterDampening; // Without this, the hoverbike will bob up and down on the water erratically when not piloted. // And we have to do it in PhysicsMove because piloted/not piloted changes more often than PostUpgradeModuleChange. } }
public static void OnUpdate(Hoverbike __instance) { __instance.gameObject.EnsureComponent <HoverbikeUpdater>()?.OnUpdate(__instance); }
internal void SetHoverbikeOverDrive(Hoverbike hoverbike, float multiplier) { hoverbike.forwardAccel = multiplier == 1 ? HoverBike_Default_forwardAccel : HoverBike_Default_forwardAccel * multiplier; SetHoverBikeMoveOnWater(Main.Instance.isHoverBikeMoveOnWater.value); }
internal static void Postfix(Hoverbike __instance) { __instance.gameObject.AddIfNeedComponent <HoverbikeOverDrive>(); }
internal virtual void PostUpdate(Hoverbike instance = null) { }
internal static void Prefix(Hoverbike __instance) { __instance.SetPrivateField("slotIDs", SlotHelper.NewHoverbikeSlotIDs); BZLogger.Debug($"Hoverbike slotIDs patched. ID: {__instance.GetInstanceID()}"); }
public static void PostPhysicsMove(Hoverbike __instance) { __instance.gameObject.EnsureComponent <HoverbikeUpdater>()?.PostPhysicsMove(__instance); }
public static void PostUpgradeModuleChange(Hoverbike __instance, int slotID, TechType techType, bool added) { __instance.gameObject.EnsureComponent <HoverbikeUpdater>()?.PostUpgradeModuleChange(slotID, techType, added, __instance); }
public static void PostUpdateEnergy(Hoverbike __instance) { __instance.gameObject?.EnsureComponent <HoverbikeUpdater>().PostUpdateEnergy(__instance); }
internal virtual void PostUpgradeModuleChange(int slotID, TechType techType, bool added, Hoverbike instance = null) { if (parentHoverbike == null) { if (instance != null) { Initialise(ref instance); } else { return; } } // My first instinct is always to use switch() in situations like this, but you can't use switch() with non-const types. if (techType == techTypeWaterTravel) { bHasTravelModule = HasTravelModule(); } else if (techType == techTypeHullModule) { parentHoverbike.gameObject.EnsureComponent <HoverbikeStructuralIntegrityModifier>().SetActive(added); } else if (techType == techTypeMobility) { bHasTravelModule = HasTravelModule(); if (GetModuleCount(TechType.HoverbikeJumpModule) < 1) { FieldInfo jump = typeof(Hoverbike).GetField("jumpEnabled", BindingFlags.Instance | BindingFlags.NonPublic); if (jump != null) { jump.SetValue(parentHoverbike, added); } } } else if (techType == techTypeRepair) { bHasSelfRepair = added; } else if (techType == techTypeDurability) { bHasSelfRepair = added; parentHoverbike.gameObject.EnsureComponent <HoverbikeStructuralIntegrityModifier>().SetActive(added); } if (TryGetDefaultFloat("enginePowerConsumption", out float defaultPowerConsumption)) { float effectiveEfficiency = 1f; int priority = 0; //Log.LogDebug($"HoverbikeUpdate.PostUpgradeModuleChange(): applying efficiency modifiers"); //foreach (EfficiencyModifier modifier in efficiencyModifiers) foreach (KeyValuePair <TechType, EfficiencyModifier> modifierPair in efficiencyModifiers) { EfficiencyModifier modifier = modifierPair.Value; //Log.LogDebug($"Using modifier {modifier.ToString()}"); //int moduleCount = GetModuleCount(modifier.techType); int moduleCount = GetModuleCount(modifierPair.Key); if (moduleCount > 0) { moduleCount = Math.Min(moduleCount, modifier.maxUpgrades); // This could've been included as part of the assignment, but this way we only do the Min() call if it's needed. if (modifier.priority > priority) { effectiveEfficiency = modifier.efficiencyMultiplier * moduleCount; priority = modifier.priority; //Log.LogDebug($"Using modifier with higher priority {priority}; effectiveEfficiency now {modifier.efficiencyMultiplier}"); } else if (modifier.priority == priority) { effectiveEfficiency *= modifier.efficiencyMultiplier * moduleCount; } // There is no else. } } float newConsumption = defaultPowerConsumption * effectiveEfficiency; Log.LogDebug($"HoverbikeUpdate.PostUpgradeModuleChange(): changed TechType {techType.AsString()}; found defaultPowerConsumption of {defaultPowerConsumption} and calculated new power consumption of {newConsumption}"); parentHoverbike.enginePowerConsumption = newConsumption; } if (TryGetDefaultFloat(nameof(Hoverbike.forwardAccel), out float defaultForwardAccel) && TryGetDefaultFloat(nameof(Hoverbike.forwardBoostForce), out float defaultBoost) && TryGetDefaultFloat(nameof(Hoverbike.boostCooldown), out float defaultCooldown) && TryGetDefaultFloat(nameof(Hoverbike.jumpCooldown), out float defaultJumpCooldown)) { float speedMult = 1f; float cooldownMult = 1f; int priority = 0; //Log.LogDebug($"HoverbikeUpdate.PostUpgradeModuleChange(): applying movement modifiers"); //foreach (MovementModifierStruct modifier in movementModifiers) foreach (KeyValuePair <TechType, MovementModifier> modifierPair in movementModifiers) { //Log.LogDebug($"Using modifier {modifier.ToString()}"); MovementModifier modifier = modifierPair.Value; int moduleCount = GetModuleCount(modifierPair.Key); if (moduleCount > 0) { moduleCount = Math.Min(moduleCount, modifier.maxUpgrades); if (modifier.priority > priority) { speedMult = modifier.speedModifier * moduleCount; cooldownMult = modifier.cooldownModifier * moduleCount; priority = modifier.priority; //Log.LogDebug($"Using modifier with higher priority {priority}; speedMult now {speedMult}, cooldownMult now {cooldownMult}"); } else if (modifier.priority == priority) { speedMult *= modifier.speedModifier * moduleCount; cooldownMult *= modifier.cooldownModifier * moduleCount; //Log.LogDebug($"Using modifier with equal priority {priority}; speedMult now {speedMult}, cooldownMult now {cooldownMult}"); } // There is no else. } } parentHoverbike.forwardAccel = defaultForwardAccel * speedMult; parentHoverbike.forwardBoostForce = defaultBoost * speedMult; parentHoverbike.boostCooldown = defaultCooldown * cooldownMult; parentHoverbike.jumpCooldown = defaultJumpCooldown * cooldownMult; } }
public static void Postfix(Hoverbike __instance) { __instance.gameObject.EnsureComponent <WaterRideManager>(); BZLogger.Debug("HoverbikeWaterRideModule", $"Water Ride Manager added in Hoverbike.Start -> Postfix Patch. ID: {__instance.gameObject.GetInstanceID()}"); }
internal virtual void PostPhysicsMove(Hoverbike instance = null) { }