diff --git a/QSB/AuthoritySync/IAuthWorldObject.cs b/QSB/AuthoritySync/IAuthWorldObject.cs new file mode 100644 index 00000000..323f4849 --- /dev/null +++ b/QSB/AuthoritySync/IAuthWorldObject.cs @@ -0,0 +1,15 @@ +using QSB.WorldSync; + +namespace QSB.AuthoritySync; + +/// +/// a world object that has an owner +/// +public interface IAuthWorldObject : IWorldObject +{ + public uint Owner { get; set; } + /// + /// can the world object have authority + /// + public bool CanOwn { get; } +} diff --git a/QSB/AuthoritySync/WorldObjectAuthMessage.cs b/QSB/AuthoritySync/WorldObjectAuthMessage.cs new file mode 100644 index 00000000..d4269520 --- /dev/null +++ b/QSB/AuthoritySync/WorldObjectAuthMessage.cs @@ -0,0 +1,45 @@ +using QSB.Messaging; +using QSB.Player; + +namespace QSB.AuthoritySync; + +/// +/// request ownership of a world object +/// +public class WorldObjectAuthMessage : QSBWorldObjectMessage +{ + public WorldObjectAuthMessage(uint owner) : base(owner) { } + + public override bool ShouldReceive + { + get + { + if (!base.ShouldReceive) + { + return false; + } + + // Deciding if to change the object's owner + // Message + // | = 0 | > 0 | + // = 0 | No | Yes | + // > 0 | Yes | No | + // if Obj==Message then No + // Obj + + return (WorldObject.Owner == 0 || Data == 0) && WorldObject.Owner != Data; + } + } + + public override void OnReceiveLocal() => WorldObject.Owner = Data; + + public override void OnReceiveRemote() + { + WorldObject.Owner = Data; + if (WorldObject.Owner == 0 && WorldObject.CanOwn) + { + // object has no owner, but is still active for this player. request ownership + WorldObject.SendMessage(new WorldObjectAuthMessage(QSBPlayerManager.LocalPlayerId)); + } + } +}