// Currently, we only apply live mixin updates to vehicles as there is more work to implement // damage for regular entities like fish. public bool IsWhitelistedUpdateType(LiveMixin entity) { Vehicle vehicle = entity.GetComponent <Vehicle>(); SubRoot subRoot = entity.GetComponent <SubRoot>(); return(vehicle != null || (subRoot != null && subRoot.isCyclops)); }
static void KillFish(LiveMixin liveMixin) { //ErrorMessage.AddDebug("Kill " + liveMixin.gameObject.name); //Main.Log("Kill " + liveMixin.gameObject.name); liveMixin.health = 0f; liveMixin.tempDamage = 0f; liveMixin.SyncUpdatingState(); if (liveMixin.deathClip) { Utils.PlayEnvSound(liveMixin.deathClip, liveMixin.transform.position, 25f); } //if (this.deathEffect != null) // Utils.InstantiateWrap(this.deathEffect, this.transform.position, Quaternion.identity); if (liveMixin.passDamageDataOnDeath) { liveMixin.gameObject.BroadcastMessage("OnKill", DamageType.Normal, SendMessageOptions.DontRequireReceiver); } else if (liveMixin.broadcastKillOnDeath) { liveMixin.gameObject.BroadcastMessage("OnKill", SendMessageOptions.DontRequireReceiver); } CreatureDeath creatureDeath = liveMixin.GetComponent <CreatureDeath>(); Eatable eatable = liveMixin.GetComponent <Eatable>(); eatable.SetDecomposes(true); Rigidbody rb = liveMixin.GetComponent <Rigidbody>(); if (rb) { rb.isKinematic = false; rb.constraints = RigidbodyConstraints.None; WorldForces worldForces = liveMixin.GetComponent <WorldForces>(); if (worldForces) { worldForces.handleDrag = false; } rb.drag = Mathf.Max(rb.drag, 1f); rb.angularDrag = Mathf.Max(rb.angularDrag, 1f); } liveMixin.gameObject.EnsureComponent <EcoTarget>().SetTargetType(EcoTargetType.DeadMeat); if (creatureDeath) { if (creatureDeath.respawn && !creatureDeath.respawnOnlyIfKilledByCreature) { creatureDeath.SpawnRespawner(); } if (creatureDeath.removeCorpseAfterSeconds >= 0.0) { creatureDeath.Invoke("RemoveCorpse", creatureDeath.removeCorpseAfterSeconds); } creatureDeath.SyncFixedUpdatingState(); } }
/// <summary> /// Indicates if a LiveMixin object should execute TakeDamage or HealthBack method /// </summary> /// <param name="reciever">The one who takes damage or gets health back</param> /// <param name="healthChange">The amount of health it gets back or damage dealt</param> /// <param name="dealer">Damage dealer</param> /// <returns>Tuple where the first item indicates execution and the second indicates if the player has the ownership of the reciever GameObject (if vehicle)</returns> public ExecutionAndOwnership ShouldExecute(LiveMixin reciever, float healthChange, GameObject dealer) { Vehicle vehicle = reciever.GetComponent <Vehicle>(); SubRoot subRoot = reciever.GetComponent <SubRoot>(); if (vehicle != null || subRoot != null && subRoot.isCyclops) { NitroxId id = NitroxEntity.GetId(reciever.gameObject); bool isOutstandingPresent = outstandingChangeHealth.TryGetValue(id, out Tuple <float, float> healthChangeAndTotal) && healthChangeAndTotal.Item1 == healthChange && healthChangeAndTotal.Item2 == reciever.health; bool hasOwnership = simulationOwnership.HasAnyLockType(id); // We either have a lock or an outstanding health change with the same health change and current total health when we execute the code if (!hasOwnership && !isOutstandingPresent) { return(new ExecutionAndOwnership(false, false)); } // Remove the outstandingHealthChange if present. if (isOutstandingPresent) { outstandingChangeHealth.Remove(id); } if (healthChange > 0) { return(new ExecutionAndOwnership(true, hasOwnership)); } // To prevent damage that happens while docking, we check if dealer is the vehicle that is also docked. VehicleDockingBay vehicleDockingBay = reciever.GetComponent <VehicleDockingBay>(); if (!vehicleDockingBay) { vehicleDockingBay = reciever.GetComponentInChildren <VehicleDockingBay>(); } Vehicle dealerVehicle = dealer.GetComponent <Vehicle>(); if (vehicleDockingBay && dealerVehicle) { if (vehicleDockingBay.GetDockedVehicle() == dealerVehicle || (Vehicle)vehicleDockingBay.ReflectionGet("interpolatingVehicle") == dealerVehicle || (Vehicle)vehicleDockingBay.ReflectionGet("nearbyVehicle") == dealerVehicle) { Log.Debug($"Dealer {dealer} is vehicle and currently docked or nearby {reciever}, do not harm it!"); return(new ExecutionAndOwnership(false, false)); } } return(new ExecutionAndOwnership(true, hasOwnership)); } return(new ExecutionAndOwnership(true, false)); }
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); }
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); }
static void KillFish(LiveMixin liveMixin) { //AddDebug("KillFish " + liveMixin.gameObject.name); //Main.Log("Kill " + liveMixin.gameObject.name); liveMixin.health = 0f; liveMixin.tempDamage = 0f; liveMixin.SyncUpdatingState(); //if (liveMixin.deathClip) // liveMixin.deathClip.Play(); //if (liveMixin.deathSound) // Utils.PlayFMODAsset(liveMixin.deathSound, liveMixin.transform); //if (liveMixin.passDamageDataOnDeath) // liveMixin.gameObject.BroadcastMessage("OnKill", DamageType.Normal, SendMessageOptions.DontRequireReceiver); //else if (liveMixin.broadcastKillOnDeath) // liveMixin.gameObject.BroadcastMessage("OnKill", SendMessageOptions.DontRequireReceiver); //if (liveMixin.sendKillOnDeath) //{ // if (liveMixin.passDamageDataOnDeath) // liveMixin.gameObject.SendMessage("OnKill", DamageType.Normal, SendMessageOptions.DontRequireReceiver); // else // liveMixin.gameObject.SendMessage("OnKill", SendMessageOptions.DontRequireReceiver); //} AquariumFish af = liveMixin.GetComponent <AquariumFish>(); if (af) { UnityEngine.Object.Destroy(af); } Locomotion locomotion = liveMixin.GetComponent <Locomotion>(); locomotion.enabled = false; CreatureDeath creatureDeath = liveMixin.GetComponent <CreatureDeath>(); Eatable eatable = liveMixin.GetComponent <Eatable>(); eatable.SetDecomposes(true); Rigidbody rb = liveMixin.GetComponent <Rigidbody>(); if (rb) { rb.isKinematic = false; rb.constraints = RigidbodyConstraints.None; WorldForces worldForces = liveMixin.GetComponent <WorldForces>(); if (worldForces) { worldForces.handleDrag = false; } rb.drag = Mathf.Max(rb.drag, 1f); rb.angularDrag = Mathf.Max(rb.angularDrag, 1f); } liveMixin.gameObject.EnsureComponent <EcoTarget>().SetTargetType(EcoTargetType.DeadMeat); if (creatureDeath) { if (creatureDeath.respawn && !creatureDeath.respawnOnlyIfKilledByCreature) { creatureDeath.SpawnRespawner(); } if (creatureDeath.removeCorpseAfterSeconds >= 0.0) { creatureDeath.Invoke("RemoveCorpse", creatureDeath.removeCorpseAfterSeconds); } creatureDeath.SyncFixedUpdatingState(); } Pickupable pickupable = liveMixin.GetComponent <Pickupable>(); ItemsContainer container = pickupable.inventoryItem.container as ItemsContainer; if (container != null) { // fix offset decay bar container.RemoveItem(pickupable, true); container.AddItem(pickupable); } }