using Barotrauma.Items.Components; using Barotrauma.Networking; using System; namespace Barotrauma.MapCreatures.Behavior { partial class BallastFloraBehavior { const float DamageUpdateInterval = 1.0f; private float damageUpdateTimer; partial void LoadPrefab(ContentXElement element) { foreach (var subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "branchsprite": case "hiddenflowersprite": break; case "flowersprite": flowerVariants++; break; case "leafsprite": leafVariants++; break; case "targets": LoadTargets(subElement); break; } } } partial void UpdateDamage(float deltaTime) { damageUpdateTimer -= deltaTime; if (damageUpdateTimer > 0.0f) { return; } const int maxMessagesPerSecond = 10; int messages = 0; foreach (BallastFloraBranch branch in Branches) { //don't notify about minuscule amounts of damage (<= 1.0f) if (Math.Abs(branch.AccumulatedDamage) > 1.0f) { CreateNetworkMessage(new BranchDamageEventData(branch)); branch.AccumulatedDamage = 0.0f; messages++; //throttle a bit: if a large ballast flora is withering, it can lead to a very large number of events otherwise if (messages > maxMessagesPerSecond) { break; } } } damageUpdateTimer = DamageUpdateInterval; } public void ServerWrite(IWriteMessage msg, IEventData eventData) { msg.WriteByte((byte)eventData.NetworkHeader); switch (eventData) { case SpawnEventData _: ServerWriteSpawn(msg); break; case KillEventData _: //do nothing break; case BranchCreateEventData branchCreateEventData: ServerWriteBranchGrowth(msg, branchCreateEventData.NewBranch, branchCreateEventData.Parent.ID); break; case BranchDamageEventData branchDamageEventData: ServerWriteBranchDamage(msg, branchDamageEventData.Branch); break; case InfectEventData infectEventData: ServerWriteInfect(msg, infectEventData.Item.ID, infectEventData.Infect, infectEventData.Infector); break; case BranchRemoveEventData branchRemoveEventData: ServerWriteBranchRemove(msg, branchRemoveEventData.Branch); break; } msg.WriteSingle(PowerConsumptionTimer); } private void ServerWriteSpawn(IWriteMessage msg) { msg.WriteIdentifier(Prefab.Identifier); msg.WriteSingle(Offset.X); msg.WriteSingle(Offset.Y); } private void ServerWriteBranchGrowth(IWriteMessage msg, BallastFloraBranch branch, int parentId = -1) { var (x, y) = branch.Position; msg.WriteInt32(parentId); msg.WriteInt32((int)branch.ID); msg.WriteBoolean(branch.IsRootGrowth); msg.WriteRangedInteger((byte)branch.Type, 0b0000, 0b1111); msg.WriteRangedInteger((byte)branch.Sides, 0b0000, 0b1111); msg.WriteRangedInteger(branch.FlowerConfig.Serialize(), 0, 0xFFF); msg.WriteRangedInteger(branch.LeafConfig.Serialize(), 0, 0xFFF); msg.WriteUInt16((ushort)branch.MaxHealth); msg.WriteInt32((int)(x / VineTile.Size)); msg.WriteInt32((int)(y / VineTile.Size)); msg.WriteInt32(branch.ParentBranch == null ? -1 : Branches.IndexOf(branch.ParentBranch)); } private void ServerWriteBranchDamage(IWriteMessage msg, BallastFloraBranch branch) { msg.WriteInt32((int)branch.ID); msg.WriteSingle(branch.Health); } private void ServerWriteInfect(IWriteMessage msg, UInt16 itemID, InfectEventData.InfectState infect, BallastFloraBranch infector = null) { msg.WriteUInt16(itemID); msg.WriteBoolean(infect == InfectEventData.InfectState.Yes); if (infect == InfectEventData.InfectState.Yes) { msg.WriteInt32(infector?.ID ?? -1); } } private void ServerWriteBranchRemove(IWriteMessage msg, BallastFloraBranch branch) { msg.WriteInt32(branch.ID); } public void CreateNetworkMessage(IEventData extraData) { GameMain.Server.CreateEntityEvent(Parent, new Hull.BallastFloraEventData(this, extraData)); } } }