예제 #1
0
        public static bool Prefix(out float?__state, LiveMixin __instance)
        {
            __state = null;

            LiveMixinManager liveMixinManager = NitroxServiceLocator.LocateService <LiveMixinManager>();

            if (!liveMixinManager.IsWhitelistedUpdateType(__instance))
            {
                return(true); // everyone should process this locally
            }

            // Persist the previous health value
            __state = __instance.health;

            return(liveMixinManager.ShouldApplyNextHealthUpdate(__instance));
        }
        public static void AddFishToList(ItemsContainer container = null)
        {
            bool underWater = Player.main.IsUnderwaterForSwimming();

            //AddDebug("run AddFishToList ");
            if (container == null)
            {
                container = Inventory.main.container;
            }

            foreach (InventoryItem item in container)
            {
                //ErrorMessage.AddDebug("AddFishToList "+ item.item.gameObject.name);
                if (IsEatableFishAlive(item.item.gameObject))
                {
                    LiveMixin liveMixin = item.item.GetComponent <LiveMixin>();
                    //Main.Log("AddFishToList " + liveMixin.gameObject.name);
                    if (underWater)
                    {
                        if (fishOutOfWater.ContainsKey(liveMixin))
                        {
                            //ErrorMessage.AddDebug("remove fish " + liveMixin.gameObject.name);
                            //Main.Log("remove fish " + liveMixin.gameObject.name);
                            if (DayNightCycle.main.timePassedAsFloat - fishOutOfWater[liveMixin] > Main.config.outOfWaterLifeTime * 60f)
                            {
                                KillFish(liveMixin);
                            }

                            fishOutOfWater.Remove(liveMixin);
                        }
                    }
                    else
                    {
                        if (fishOutOfWater.ContainsKey(liveMixin))
                        {
                            CheckFish(liveMixin);
                        }
                        else
                        {
                            //ErrorMessage.AddDebug("Add fish " + liveMixin.gameObject.name);
                            fishOutOfWater.Add(liveMixin, DayNightCycle.main.timePassedAsFloat);
                        }
                    }
                }
            }
        }
        public static bool InflictDamage(LiveMixin instance, float originalDamage, Vector3 position = default(Vector3), DamageType type = DamageType.Normal, GameObject dealer = null)
        {
            Log.LogDebug($"ExosuitClawArmPatches.InflictDamage running, instance {instance?.name}, originalDamage {originalDamage}, position ({position.ToString()}, type {type.ToString()}, dealer "
                         + (dealer == null ? "null" : dealer.name));
            bool result = instance.TakeDamage(originalDamage, position, type, dealer);

            if (type != DamageType.Electrical)
            {
                Exosuit exosuit = Player.main.GetVehicle() as Exosuit;
                if (exosuit?.modules != null &&              // This shouldn't fail, but this is here for paranoia's sake
                    exosuit.modules.GetCount(LightningGeneratorTechType) > 0)
                {
                    result |= instance.TakeDamage(originalDamage * damageMultiplier, position, DamageType.Electrical, dealer);
                }
            }
            return(result);
        }
            public static void Postfix(Pickupable __instance, Vector3 dropPosition)
            {
                LiveMixin liveMixin = __instance.GetComponent <LiveMixin>();

                if (liveMixin && fishOutOfWater.ContainsKey(liveMixin))
                {
                    if (Player.main.IsUnderwater())
                    {
                        //AddDebug("reset time " + liveMixin.gameObject.name);
                        fishOutOfWater.Remove(liveMixin);
                    }
                    else
                    {
                        CheckFish(liveMixin);
                    }
                }
            }
        new public void OnHit()
        {
            Exosuit componentInParent = base.GetComponentInParent <Exosuit>();

            if (componentInParent.CanPilot() && componentInParent.GetPilotingMode())
            {
                Vector3    position   = default;
                GameObject gameObject = null;
                Vector3    vector;
                UWE.Utils.TraceFPSTargetPosition(componentInParent.gameObject, 6.5f, ref gameObject, ref position, out vector, true);
                if (gameObject == null)
                {
                    InteractionVolumeUser component = Player.main.gameObject.GetComponent <InteractionVolumeUser>();
                    if (component != null && component.GetMostRecent() != null)
                    {
                        gameObject = component.GetMostRecent().gameObject;
                    }
                }
                if (gameObject)
                {
                    LiveMixin liveMixin = gameObject.FindAncestor <LiveMixin>();
                    if (liveMixin)
                    {
                        liveMixin.IsAlive();
                        liveMixin.TakeDamage(50f, position, DamageType.Normal, null);
                        // Originally the change was from Normal to Electrical, but there should be a Normal component and an Electrical.
                        // Without a Normal component to the damage, Eye Jellies (to use one example) give no f***s about being twatted in the eye with a Lightning Claw.
                        // That's not right; even if the electrical damage does nothing for them, it's a chunk of heavy metal being propelled at high speed by precision hydraulics.
                        Log.LogDebug($"ExosuitLightningClaw: inflicting Electrical damage on target {gameObject.ToString()}");
                        liveMixin.TakeDamage(30f, position, DamageType.Electrical, null);                         // Animals treat this as over 1000 damage when deciding whether to flee or not.
                        // Curiously, Snow Stalkers appear to give no f***s about any sort of damage, and will continue pursuing until you either get beyond their
                        // "bollocks to this" range, or until they are dead.
                        global::Utils.PlayFMODAsset(base.hitFishSound, this.front, 50f);
                    }
                    else
                    {
                        global::Utils.PlayFMODAsset(base.hitTerrainSound, this.front, 50f);
                    }
                    VFXSurface component2 = gameObject.GetComponent <VFXSurface>();
                    Vector3    euler      = MainCameraControl.main.transform.eulerAngles + new Vector3(300f, 90f, 0f);
                    VFXSurfaceTypeManager.main.Play(component2, base.vfxEventType, position, Quaternion.Euler(euler), componentInParent.gameObject.transform);
                    gameObject.SendMessage("BashHit", this, SendMessageOptions.DontRequireReceiver);
                }
            }
        }
        public void Start()
        {
            LiveMixin liveMixin = gameObject.GetComponent <LiveMixin>();

            if (liveMixin == null)
            {
                Utilities.Log.Error("DeathManager can't find the submarines's livemixin. Destroying...");
                Destroy(this);
                return;
            }

            if (liveMixin.broadcastKillOnDeath == false)
            {
                Utilities.Log.Error("Deathmanager requires the submarine's broadcastKillOnDeath field to be set to true. Destroying...");
                Destroy(this);
                return;
            }
        }
예제 #7
0
        static void Postfix(HangingStinger __instance)
        {
            LiveMixin liveMixin = __instance.GetComponent <LiveMixin>();

            if (!deathEffect)
            {
                UWE.CoroutineHost.StartCoroutine(_deathEffect());
            }

            // can't change it just once, stingers use three LiveMixinData (short, middle, long)
            liveMixin.data.destroyOnDeath = true;
#if GAME_SN
            liveMixin.data.explodeOnDestroy = false;
#endif
            liveMixin.data.deathEffect = deathEffect;
            liveMixin.data.maxHealth   = maxHealth;

            liveMixin.health = liveMixin.data.maxHealth;
        public static bool Prefix(ref SubRoot __instance)
        {
            LiveMixin cyclopsLife = __instance.live;

            if (cyclopsLife == null || !cyclopsLife.IsAlive())
            {
                return(true); // safety check
            }
            var mgr = CyclopsManager.GetManager(__instance);

            if (mgr == null)
            {
                return(true); // Safety Check
            }
            mgr.Upgrade.HandleUpgrades();

            // No need to execute original method anymore
            return(false); // Completely override the method and do not continue with original execution
        }
        private static void CheckFish(LiveMixin liveMixin)
        {
            if (!fishOutOfWater.ContainsKey(liveMixin))
            {
                return;
            }

            float timeOutOfWater = DayNightCycle.main.timePassedAsFloat - fishOutOfWater[liveMixin];

            if (timeOutOfWater > Main.config.outOfWaterLifeTime * 60f)
            {
                //AddDebug("KillFish " + liveMixin.gameObject.name + " " + timeOutOfWater.ToString("0.0"));
                //Main.Log("Kill " + liveMixin.gameObject.name + " " + timeOutOfWater.ToString("0.0"));
                fishOutOfWater.Remove(liveMixin);
                KillFish(liveMixin);
            }
            //else
            //    AddDebug("CheckFish " + liveMixin.gameObject.name + " " + timeOutOfWater.ToString("0.0"));
        }
        public void OnHit()
        {
            if (TruckHelper.IsPiloted())
            {
                Vector3    position     = default(Vector3);
                GameObject targetObject = null;

                UWE.Utils.TraceFPSTargetPosition(TruckHelper.MainCab, 6.5f, ref targetObject, ref position, out Vector3 normal, true);

                if (targetObject == null)
                {
                    InteractionVolumeUser component = Player.main.gameObject.GetComponent <InteractionVolumeUser>();

                    if (component != null && component.GetMostRecent() != null)
                    {
                        targetObject = component.GetMostRecent().gameObject;
                    }
                }
                if (targetObject)
                {
                    LiveMixin liveMixin = targetObject.FindAncestor <LiveMixin>();

                    if (liveMixin)
                    {
                        bool flag = liveMixin.IsAlive();
                        liveMixin.TakeDamage(50f, position, DamageType.Normal, null);
                        Utils.PlayFMODAsset(hitFishSound, front, 50f);
                    }
                    else
                    {
                        Utils.PlayFMODAsset(hitTerrainSound, front, 50f);
                    }

                    VFXSurface component2 = targetObject.GetComponent <VFXSurface>();

                    Vector3 euler = MainCameraControl.main.transform.eulerAngles + new Vector3(300f, 90f, 0f);

                    VFXSurfaceTypeManager.main.Play(component2, vfxEventType, position, Quaternion.Euler(euler), TruckHelper.MainCab.transform);

                    targetObject.SendMessage("BashHit", this, SendMessageOptions.DontRequireReceiver);
                }
            }
        }
예제 #11
0
            public static void SaveOnEntry(SubRoot __instance)
            {
                if (UnityEngine.Time.timeSinceLevelLoad < 10.0f)
                {
                    return; // Save game load
                }
                if (__instance != null)
                {
                    if (__instance.isBase && settings.PlayerBase.SaveOnEntry)
                    {
                        if (!settings.PlayerBase.SaveEvenWhenFloodedOrDamaged && __instance.IsLeaking())
                        {
                            log("Base is leaking and settings.PlayerBase.SaveEvenWhenFloodedOrDamaged is set to false, skipping autosave!");
                            return;
                        }

                        ForceSave(settings.PlayerBase.PauseIntervalInSeconds);
                    }
                    else if (__instance.isCyclops && settings.Cyclops.SaveOnEntry)
                    {
                        // Get SubRoot.live
                        LiveMixin live = null;
                        {
                            FieldInfo f_live = __instance.GetType().GetField("live", BindingFlags.NonPublic | BindingFlags.Instance);
                            var       v_live = f_live?.GetValue(__instance);
                            live = v_live == null ? (LiveMixin)v_live : null;
                        }
                        if (live == null)
                        {
                            log("Could not get SubRoot.live on Cyclops entry, skipping autosave!");
                            return;
                        }
                        if (!settings.Cyclops.SaveEvenWhenFloodedOrDamaged &&
                            (__instance.IsLeaking() || live.GetHealthFraction() < 1.0f))
                        {
                            log("Cyclops is leaking and/or is damaged, and settings.Cyclops.SaveEvenWhenFloodedOrDamaged is set to false, skipping autosave!");
                            return;
                        }

                        ForceSave(settings.Cyclops.PauseIntervalInSeconds);
                    }
                }
            }
예제 #12
0
        public static void Postfix(float?__state, LiveMixin __instance, float originalDamage, Vector3 position, DamageType type, GameObject dealer)
        {
            // State is only filled if we have the ownership
            if (__state.HasValue)
            {
                TechType techType = CraftData.GetTechType(__instance.gameObject);
                // Send message to other player if LiveMixin is from a vehicle and got the simulation ownership
                NitroxId id = NitroxEntity.GetId(__instance.gameObject);

                if (__state.Value != __instance.health)
                {
                    Optional <NitroxId> dealerId = Optional.Empty;
                    if (dealer)
                    {
                        dealerId = NitroxEntity.GetId(dealer);
                    }
                    NitroxServiceLocator.LocateService <LiveMixinManager>().BroadcastTakeDamage(techType, id, originalDamage, position, type, dealerId, __instance.health);
                }
            }
        }
예제 #13
0
        public override void Process(WeldAction packet)
        {
            GameObject gameObject = NitroxEntity.RequireObjectFrom(packet.Id);

            if (!simulationOwnership.HasAnyLockType(packet.Id))
            {
                Log.Error($"Got WeldAction packet for {packet.Id} but did not find the lock corresponding to it");
                return;
            }

            LiveMixin liveMixin = gameObject.GetComponent <LiveMixin>();

            if (!liveMixin)
            {
                Log.Error($"Did not find LiveMixin for GameObject {packet.Id} even though it was welded.");
                return;
            }
            // If we add other player sounds/animations, this is the place to do it for welding
            liveMixin.AddHealth(packet.HealthAdded);
        }
예제 #14
0
        private static bool IsValidTarget(LiveMixin liveMixin)
        {
            if (!liveMixin)
            {
                return(true);
            }

            if (liveMixin.weldable)
            {
                return(false);
            }

            if (!liveMixin.knifeable)
            {
                return(false);
            }
            EscapePod component = liveMixin.GetComponent <EscapePod>();

            return(!component);
        }
예제 #15
0
        void Drill(SeaMoth moth)
        {
            var pos    = Vector3.zero;
            var hitObj = default(GameObject);

            // Get the GameObject we're looking at
            UWE.Utils.TraceFPSTargetPosition(moth.gameObject, 6f, ref hitObj, ref pos, true);

            // Check if not null
            if (hitObj)
            {
                // Find the BetterDrillable component and play sounds.
                var drillable = hitObj.FindAncestor <BetterDrillable>();
                Main.DrillLoopHit.Play();

                // If we found the drillable
                if (drillable)
                {
                    // Send the "drill" message to the Drillable
                    drillable.OnDrill(transform.position, moth, out GameObject hitMesh);
                }
                else // Otherwise if we did not hit a drillable object
                {
                    // Get the LiveMixin component in the found GameObject
                    LiveMixin liveMixin = hitObj.FindAncestor <LiveMixin>();
                    if (liveMixin) // If not null
                    {
                        // Make it take a bit of damage
                        liveMixin.TakeDamage(4f, pos, DamageType.Drill, null);
                    }

                    // Also send a "hit" message.
                    hitObj.SendMessage("BashHit", this, SendMessageOptions.DontRequireReceiver);
                }
            }
            else // If its null
            {
                // Stop all sounds
                StopEffects();
            }
        }
 public static void PrintAllLiveMixinDetails(this LiveMixin liveMixin)
 {
     Log.Print("LiveMixin broadcastKillOnDeath: " + liveMixin.broadcastKillOnDeath);
     Log.Print("LiveMixin canResurrect: " + liveMixin.canResurrect);
     Log.Print("LiveMixin damageEffect: " + liveMixin.damageEffect);
     Log.Print("LiveMixin deathEffect: " + liveMixin.deathEffect);
     Log.Print("LiveMixin destroyOnDeath: " + liveMixin.destroyOnDeath);
     Log.Print("LiveMixin electricalDamageEffect: " + liveMixin.electricalDamageEffect);
     Log.Print("LiveMixin explodeOnDestroy: " + liveMixin.explodeOnDestroy);
     Log.Print("LiveMixin invincibleInCreative: " + liveMixin.invincibleInCreative);
     Log.Print("LiveMixin knifeable: " + liveMixin.knifeable);
     Log.Print("LiveMixin loopEffectBelowPercent: " + liveMixin.loopEffectBelowPercent);
     Log.Print("LiveMixin loopingDamageEffect: " + liveMixin.loopingDamageEffect);
     Log.Print("LiveMixin maxHealth: " + liveMixin.maxHealth);
     Log.Print("LiveMixin minDamageForSound: " + liveMixin.minDamageForSound);
     Log.Print("LiveMixin passDamageDataOnDeath: " + liveMixin.passDamageDataOnDeath);
     Log.Print("LiveMixin weldable: " + liveMixin.weldable);
     Log.Print("LiveMixin damageClip: " + liveMixin.damageClip);
     Log.Print("LiveMixin data: " + liveMixin.data);
     Log.Print("LiveMixin deathClip: " + liveMixin.deathClip);
     Log.Print("LiveMixin health: " + liveMixin.health);
     Log.Print("LiveMixin invincible: " + liveMixin.invincible);
     Log.Print("LiveMixin onHealDamage: " + liveMixin.onHealDamage);
     Log.Print("LiveMixin onHealTempDamage: " + liveMixin.onHealTempDamage);
     Log.Print("LiveMixin shielded: " + liveMixin.shielded);
     Log.Print("LiveMixin data broadcastKillOnDeath: " + liveMixin.data.broadcastKillOnDeath);
     Log.Print("LiveMixin data canResurrect: " + liveMixin.data.canResurrect);
     Log.Print("LiveMixin data damageEffect: " + liveMixin.data.damageEffect);
     Log.Print("LiveMixin data deathEffect: " + liveMixin.data.deathEffect);
     Log.Print("LiveMixin data destroyOnDeath: " + liveMixin.data.destroyOnDeath);
     Log.Print("LiveMixin data electricalDamageEffect: " + liveMixin.data.electricalDamageEffect);
     Log.Print("LiveMixin data explodeOnDestroy: " + liveMixin.data.explodeOnDestroy);
     Log.Print("LiveMixin data invincibleInCreative: " + liveMixin.data.invincibleInCreative);
     Log.Print("LiveMixin data knifeable: " + liveMixin.data.knifeable);
     Log.Print("LiveMixin data loopEffectBelowPercent: " + liveMixin.data.loopEffectBelowPercent);
     Log.Print("LiveMixin data loopingDamageEffect: " + liveMixin.data.loopingDamageEffect);
     Log.Print("LiveMixin data maxHealth: " + liveMixin.data.maxHealth);
     Log.Print("LiveMixin data minDamageForSound: " + liveMixin.data.minDamageForSound);
     Log.Print("LiveMixin data passDamageDataOnDeath: " + liveMixin.data.passDamageDataOnDeath);
     Log.Print("LiveMixin data weldable: " + liveMixin.data.weldable);
 }
예제 #17
0
        private void UpdateSpawn()
        {
            // If eggs model changed, refresh eggs status and next spawn time
            bool flag = HasEggs();

            if (this.hasEggs != flag)
            {
                this.hasEggs       = flag;
                this.timeNextSpawn = this.CalculateTimeNextSpawn();
            }

            if (this.hasEggs && this.timeNextSpawn > 0f && Time.time > this.timeNextSpawn && this.TryGetSpawnPosition(this.gameObject.transform.position, out Vector3 position))
            {
                GameObject item      = UnityEngine.Object.Instantiate <GameObject>(GhostLeviatanSpawner.ghostLeviathanPrefab, position, Quaternion.identity);
                LiveMixin  liveMixin = item.GetComponent <LiveMixin>();
                liveMixin.data.maxHealth = ConfigSwitcher.GhostLeviatan_health;
                liveMixin.health         = ConfigSwitcher.GhostLeviatan_health;
                this.spawnedCreatures.Add(item);
                this.timeNextSpawn = this.CalculateTimeNextSpawn();
            }
        }
예제 #18
0
        public void OnCollisionEnter(Collision col)
        {
            LiveMixin mixin = col.collider.GetComponent <LiveMixin>();

            if (mixin && mixin != Player.main.liveMixin)
            {
                mixin.TakeDamage(500f);
                transform.GetChild(0).parent = null;
                Destroy(gameObject);
                return;
            }
            BreakableResource res = col.collider.GetComponent <BreakableResource>();

            if (res)
            {
                res.BreakIntoResources();
                transform.GetChild(0).parent = null;
                Destroy(gameObject);
                return;
            }
        }
        internal void Initialize(OxStationController mono)
        {
            QuickLogger.Debug("Health Initialize");
            _mono            = mono;
            _liveMixin       = mono.gameObject.AddComponent <LiveMixin>();
            _damagePerSecond = DayNight / DamagePerDay;

            if (_liveMixin != null)
            {
                if (_liveMixin.data == null)
                {
                    QuickLogger.Debug($"Creating Data");
                    _liveMixin.data = CustomLiveMixinData.Get();
                    QuickLogger.Debug($"Created Data");
                }
            }
            else
            {
                QuickLogger.Error($"LiveMixing not found!");
            }
        }
예제 #20
0
        /// <summary>
        /// This is the first thing to set before using this controller.
        /// If no live mixing data in supplied it will use the default live mixing data in <see cref="AISolutionsData.CustomLiveMixinData.Get"/>
        /// </summary>
        /// <param name="liveMixinData"></param>
        public void Startup(LiveMixin liveMixin, LiveMixinData liveMixinData)
        {
            if (liveMixin == null)
            {
                Log.Error($"{typeof(HealthController)}|| LiveMixing cannot be null!");
                return;
            }

            LiveMixin = liveMixin;

            if (liveMixinData == null)
            {
                Log.Error($"LiveMixing Data  is null!");
                Log.Info($"Creating Data");
                LiveMixin.data = AISolutionsData.CustomLiveMixinData.Get();
                Log.Info($"Created Data");
            }
            else
            {
                LiveMixin.data = liveMixinData;
            }
        }
        /// <summary>
        /// This is the first thing to set before using this controller.
        /// If no live mixing data in supplied it will use the default live mixing data in <see cref="CustomLiveMixinData.Get"/>
        /// </summary>
        /// <param name="liveMixinData"></param>
        public void Initialize(LiveMixin liveMixin, LiveMixinData liveMixinData = null)
        {
            if (liveMixin == null)
            {
                QuickLogger.Error($"{typeof(HealthController)}|| LiveMixing cannot be null!");
                return;
            }

            LiveMixin = liveMixin;

            if (liveMixinData == null)
            {
                QuickLogger.Error($"LiveMixing Data  is null!");
                QuickLogger.Info($"Creating Data");
                LiveMixin.data = CustomLiveMixinData.Get();
                QuickLogger.Info($"Created Data");
            }
            else
            {
                LiveMixin.data = liveMixinData;
            }
        }
        public override void Process(CyclopsDamage packet)
        {
            SubRoot subRoot = GuidHelper.RequireObjectFrom(packet.Guid).GetComponent <SubRoot>();

            using (packetSender.Suppress <CyclopsDamagePointRepaired>())
            {
                SetActiveDamagePoints(subRoot, packet.DamagePointIndexes);
            }

            using (packetSender.Suppress <FireDoused>())
            {
                SetActiveRoomFires(subRoot, packet.RoomFires);
            }

            LiveMixin subHealth = subRoot.gameObject.RequireComponent <LiveMixin>();

            float oldHPPercent = (float)subRoot.ReflectionGet("oldHPPercent");

            // Client side noises. Not necessary for keeping the health synced
            if (subHealth.GetHealthFraction() < 0.5f && oldHPPercent >= 0.5f)
            {
                subRoot.voiceNotificationManager.PlayVoiceNotification(subRoot.hullLowNotification, true, false);
            }
            else if (subHealth.GetHealthFraction() < 0.25f && oldHPPercent >= 0.25f)
            {
                subRoot.voiceNotificationManager.PlayVoiceNotification(subRoot.hullCriticalNotification, true, false);
            }

            using (packetSender.Suppress <CyclopsDamage>())
            {
                // Not necessary, but used by above code whenever damage is done
                subRoot.ReflectionSet("oldHPPercent", subHealth.GetHealthFraction());

                // Apply the actual health changes
                subRoot.gameObject.RequireComponent <LiveMixin>().health = packet.SubHealth;
                subRoot.gameObject.RequireComponentInChildren <CyclopsExternalDamageManager>().subLiveMixin.health = packet.DamageManagerHealth;
                subRoot.gameObject.RequireComponent <SubFire>().liveMixin.health = packet.SubFireHealth;
            }
        }
        public void copyMeleeAttack(MeleeAttack ma)
        {
            biteAggressionThreshold = ma.biteAggressionThreshold;

            biteInterval = ma.biteInterval;

            biteDamage = ma.biteDamage;

            eatHungerDecrement = ma.eatHungerDecrement;

            eatHappyIncrement = ma.eatHappyIncrement;

            biteAggressionDecrement = ma.biteAggressionDecrement;

            attackSound = ma.attackSound;

            mouth = ma.mouth;

            lastTarget = ma.lastTarget;

            creature = ma.creature;

            liveMixin = ma.liveMixin;

            damageFX = ma.damageFX;

            animator = ma.animator;

            ignoreSameKind = ma.ignoreSameKind;

            canBiteCreature = ma.canBiteCreature;

            canBitePlayer = ma.canBitePlayer;

            canBiteVehicle = ma.canBiteVehicle;

            canBiteCyclops = ma.canBiteCyclops;
        }
        public static void Postfix(float?__state, LiveMixin __instance, float originalDamage, Vector3 position, DamageType type, GameObject dealer)
        {
            // Did we realize a change in health?
            if (__state.HasValue && __state.Value != __instance.health)
            {
                // Let others know if we have a lock on this entity
                NitroxId id      = NitroxEntity.GetId(__instance.gameObject);
                bool     hasLock = NitroxServiceLocator.LocateService <SimulationOwnership>().HasAnyLockType(id);

                if (hasLock)
                {
                    TechType            techType = CraftData.GetTechType(__instance.gameObject);
                    Optional <NitroxId> dealerId = Optional.Empty;

                    if (dealer)
                    {
                        dealerId = NitroxEntity.GetId(dealer);
                    }

                    NitroxServiceLocator.LocateService <LiveMixinManager>().BroadcastTakeDamage(techType, id, originalDamage, position, type, dealerId, __instance.health);
                }
            }
        }
        private void OnTriggerEnter(Collider collider)
        {
            if (creature.Hunger.Value < 0.2f)
            {
                return;
            }
            GameObject nibbleGameObject = collider.gameObject;

            if (liveMixin.IsAlive() && !frozen)
            {
                timeStartNibbling = Time.time;
                EcoTarget ecoTarget = nibbleGameObject.GetComponentInParent <EcoTarget>();
                LiveMixin lm        = nibbleGameObject.GetComponentInParent <LiveMixin>();
                bool      isDead    = (lm != null && !lm.IsAlive()) || (ecoTarget != null && ecoTarget.type == EcoTargetType.DeadMeat);

                bool isSpecialConsumable = ecoTarget != null && ecoTarget.type == QPatch.clownPincherSpecialEdible;

                if (isDead || isSpecialConsumable)
                {
                    objectEating = collider.gameObject;
                }
            }
        }
        private void UpdateSpawn()
        {
            // If eggs model changed, refresh eggs status and next spawn time
            bool flag = HasEggs();

            if (this.hasEggs != flag)
            {
                this.hasEggs       = flag;
                this.timeNextSpawn = this.CalculateTimeNextSpawn();
                if (this.hasEggs && this.timeNextSpawn > 0f)
                {
                    TimeSpan t = TimeSpan.FromSeconds(this.timeNextSpawn - Time.time);
                    if (t.Hours > 0)
                    {
                        ErrorMessage.AddDebug(string.Format("Next ghost leviathan will spawn in {0} hour{1} {2} minute{3} and {4} second{5}.", t.Hours, t.Hours > 1 ? "s" : "", t.Minutes, t.Minutes > 1 ? "s" : "", t.Seconds, t.Seconds > 1 ? "s" : ""));
                    }
                    else if (t.Minutes > 0)
                    {
                        ErrorMessage.AddDebug(string.Format("Next ghost leviathan will spawn in {0} minute{1} and {2} second{3}.", t.Minutes, t.Minutes > 1 ? "s" : "", t.Seconds, t.Seconds > 1 ? "s" : ""));
                    }
                    else
                    {
                        ErrorMessage.AddDebug(string.Format("Next ghost leviathan will spawn in {0} seconds.", t.Seconds));
                    }
                }
            }

            if (this.hasEggs && this.timeNextSpawn > 0f && Time.time > this.timeNextSpawn && this.TryGetSpawnPosition(this.gameObject.transform.position, out Vector3 position))
            {
                GameObject item      = UnityEngine.Object.Instantiate <GameObject>(GhostLeviatanSpawner.ghostLeviathanPrefab, position, Quaternion.identity);
                LiveMixin  liveMixin = item.GetComponent <LiveMixin>();
                liveMixin.data.maxHealth = ConfigSwitcher.GhostLeviatan_health;
                liveMixin.health         = ConfigSwitcher.GhostLeviatan_health;
                this.spawnedCreatures.Add(item);
                this.timeNextSpawn = this.CalculateTimeNextSpawn();
            }
        }
예제 #27
0
        public void ProcessRemoteHealthChange(NitroxId id, float LifeChanged, Optional <DamageTakenData> opDamageTakenData, float totalHealth)
        {
            if (simulationOwnership.HasAnyLockType(id))
            {
                Log.Error($"Got LiveMixin change health for {id} but we have the simulation already. This should not happen!");
                return;
            }

            processingRemoteHealthChange = true;

            LiveMixin liveMixin = NitroxEntity.RequireObjectFrom(id).GetComponent <LiveMixin>();

            if (LifeChanged < 0)
            {
                DamageTakenData       damageTakenData = opDamageTakenData.OrElse(null);
                Optional <GameObject> opDealer        = damageTakenData.DealerId.HasValue ? NitroxEntity.GetObjectFrom(damageTakenData.DealerId.Value) : Optional.Empty;
                GameObject            dealer          = opDealer.HasValue ? opDealer.Value : null;
                if (!dealer && damageTakenData.DealerId.HasValue)
                {
                    Log.Warn($"Could not find entity {damageTakenData.DealerId.Value} for damage calculation. This could lead to problems.");
                }
                liveMixin.TakeDamage(-LifeChanged, damageTakenData.Position.ToUnity(), (DamageType)damageTakenData.DamageType, dealer);
            }
            else
            {
                liveMixin.AddHealth(LifeChanged);
            }

            processingRemoteHealthChange = false;

            // Check if the health calculated by the game is the same as the calculated damage from the simulator
            if (liveMixin.health != totalHealth)
            {
                Log.Warn($"Calculated health and send health for {id} do not align (Calculated: {liveMixin.health}, send:{totalHealth}). This will be correted but should be investigated");
                liveMixin.health = totalHealth;
            }
        }
예제 #28
0
        void OnHit()
        {
            if (seamoth.CanPilot() && seamoth.GetPilotingMode())
            {
                Vector3    position   = default(Vector3);
                GameObject gameObject = null;
                UWE.Utils.TraceFPSTargetPosition(seamoth.gameObject, 6.5f, ref gameObject, ref position, true);
                if (gameObject == null)
                {
                    InteractionVolumeUser component = Player.main.gameObject.GetComponent <InteractionVolumeUser>();
                    if (component != null && component.GetMostRecent() != null)
                    {
                        gameObject = component.GetMostRecent().gameObject;
                    }
                }
                if (gameObject)
                {
                    LiveMixin liveMixin = gameObject.FindAncestor <LiveMixin>();
                    if (liveMixin)
                    {
                        bool flag = liveMixin.IsAlive();
                        liveMixin.TakeDamage(50f, position, DamageType.Normal, null);
                        global::Utils.PlayFMODAsset(hitFishSound, this.front, 5f);
                    }
                    else
                    {
                        global::Utils.PlayFMODAsset(hitTerrainSound, this.front, 5f);
                    }
                    VFXSurface component2 = gameObject.GetComponent <VFXSurface>();
                    Vector3    euler      = MainCameraControl.main.transform.eulerAngles + new Vector3(300f, 90f, 0f);
                    VFXSurfaceTypeManager.main.Play(component2, VFXEventTypes.impact, position, Quaternion.Euler(euler), seamoth.gameObject.transform);
                    gameObject.SendMessage("BashHit", this, SendMessageOptions.DontRequireReceiver);
                }
            }

            this.cooldownTime = Time.time + cooldownHit;
        }
예제 #29
0
        public static float AddHealthOverride(LiveMixin live, float addHealth, Welder welder)
        {
            float result = 0f;

            if ((live.IsAlive() || live.canResurrect) && live.health < live.maxHealth)
            {
                float num       = live.health;
                float newHealth = Math.Min(live.health + addHealth, live.maxHealth);
                result = newHealth - num;

                SimulationOwnership simulationOwnership = NitroxServiceLocator.LocateService <SimulationOwnership>();
                NitroxId            id = NitroxEntity.GetId(live.gameObject);

                // For now, we only control the LiveMixin for vehicles (not even repair nodes at a cyclops)
                // If we change that, this if should be removed!
                Vehicle vehicle = live.GetComponent <Vehicle>();
                if (vehicle)
                {
                    if (simulationOwnership.HasAnyLockType(id))
                    {
                        result = live.AddHealth(addHealth);
                    }
                    else
                    {
                        // Another player simulates this entity. Send the weld info
                        Log.Debug($"Broadcast weld action for {id}");
                        NitroxServiceLocator.LocateService <LocalPlayer>().BroadcastWeld(id, addHealth);
                    }
                }
                else
                {
                    result = live.AddHealth(addHealth);
                }
            }
            return(result);
        }
예제 #30
0
        internal void Initialize(FCSDeepDrillerController mono)
        {
            _mono      = mono;
            _liveMixin = mono.gameObject.AddComponent <LiveMixin>();

            _damagePerSecond = DayNight / _damagePerDay;

            if (_liveMixin != null)
            {
                if (_liveMixin.data == null)
                {
                    QuickLogger.Debug($"Creating Data");
                    _liveMixin.data = CustomLiveMixinData.Get();
                    QuickLogger.Debug($"Created Data");
                }


                InvokeRepeating("HealthChecks", 0, 1);
            }
            else
            {
                QuickLogger.Error($"LiveMixing not found!");
            }
        }