Client distinguish between eye and mob for drawing, context menu, and verbs#2477
Client distinguish between eye and mob for drawing, context menu, and verbs#2477Ruzihm wants to merge 26 commits into
Conversation
…g draw, context menu, verbs
Co-authored-by: wixoa <wixoag@gmail.com>
|
actually - one sec. z levels and mouse events are messed up when eye is a turf. edit: should be good now |
|
Setting eye to null will stop rendering - but since that's done by setting the eye position to be in nullspace, the viewport stops clearing the render target and you just get a frozen screen: Does this warrant a pull request to RT to add a viewport option to allow target clearing if there is no eye/the eye is in null space? |
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
|
I tried my best to merge the refcounting change to Connection.Eye. I noticed that there was a redundant ref management outside of the |
|
@wixoaGit I think this PR is good for another look when you get a moment |
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
| private EntityUid _mobUid = EntityUid.Invalid; | ||
|
|
||
| // Sometimes we get mob info before we know all the net entities, so store the net entity and refer to it | ||
| public EntityUid MobUid { | ||
| get { | ||
| // if entity of mob is invalid but net entity isn't, try referring to known net entities | ||
| if (! _mobUid.IsValid() && _mobNet.IsValid() && _entityManager.TryGetEntity(_mobNet, out var ent)) { | ||
| _mobUid = ent.GetValueOrDefault(EntityUid.Invalid); | ||
| } | ||
|
|
||
| return _mobUid; | ||
| } | ||
| } |
There was a problem hiding this comment.
This is a lot of effort to avoid the single Dictionary lookup that _entitySystem.GetEntity() does. The same NetEntity also isn't guaranteed to always refer to the same EntityUid on the client due to PVS shenanigans, so the cached value could break.
| private EntityUid _mobUid = EntityUid.Invalid; | |
| // Sometimes we get mob info before we know all the net entities, so store the net entity and refer to it | |
| public EntityUid MobUid { | |
| get { | |
| // if entity of mob is invalid but net entity isn't, try referring to known net entities | |
| if (! _mobUid.IsValid() && _mobNet.IsValid() && _entityManager.TryGetEntity(_mobNet, out var ent)) { | |
| _mobUid = ent.GetValueOrDefault(EntityUid.Invalid); | |
| } | |
| return _mobUid; | |
| } | |
| } | |
| public EntityUid MobUid => _entityManager.GetEntity(_mobNet); |
| var prevMobNet = _mobNet; | ||
| _mobNet = msg.MobNetEntity; | ||
|
|
||
| if (prevMobNet != _mobNet) { | ||
| // mark mob cache as dirty/invalid | ||
| _mobUid = EntityUid.Invalid; | ||
| } |
There was a problem hiding this comment.
| var prevMobNet = _mobNet; | |
| _mobNet = msg.MobNetEntity; | |
| if (prevMobNet != _mobNet) { | |
| // mark mob cache as dirty/invalid | |
| _mobUid = EntityUid.Invalid; | |
| } | |
| _mobNet = msg.MobNetEntity; |
| } | ||
|
|
||
| [ViewVariables] public DreamObjectMovable? Eye { | ||
| [ViewVariables] public ClientObjectReference? Eye { |
There was a problem hiding this comment.
ClientObjectReference is intended to only be used on the client or in network communication with the client. Using it like this adds an annoying amount of indirection. This should be a DreamObjectAtom? and DreamManager.GetClientReference() should be used when creating the MsgNotifyMobEyeUpdate.
| // Type = Client -> null | ||
| public ClientObjectReference EyeRef; |
There was a problem hiding this comment.
Would ClientObjectReference? work better here than treating Client as null?
| RefType eyeType = (RefType)buffer.ReadInt32(); | ||
| switch (eyeType) { | ||
| case RefType.Entity: | ||
| EyeRef = new(new NetEntity(buffer.ReadInt32())); | ||
| break; | ||
| case RefType.Turf: | ||
| int x = buffer.ReadInt32(); | ||
| int y = buffer.ReadInt32(); | ||
| int z = buffer.ReadInt32(); | ||
| EyeRef = new(new(x, y), z); | ||
| break; | ||
| default: | ||
| // null eye | ||
| EyeRef = new(); | ||
| break; | ||
| } |
There was a problem hiding this comment.
I don't like having the process for DreamClientReference serialization in here. I'd rather this either be a helper method on DreamClientReference, use the serializer this method is given, or have this net message converted to an entity system event.
| /// Draws this plane's mouse map onto the current render target | ||
| /// </summary> | ||
| public void DrawMouseMap(DrawingHandleWorld handle, DreamViewOverlay overlay, Vector2i renderTargetSize, Box2 worldAABB) { | ||
| public void DrawMouseMap(DrawingHandleWorld handle, DreamViewOverlay overlay, Vector2i renderTargetSize, Box2 worldAABB, bool onlyDrawScreenSprites = false) { |
There was a problem hiding this comment.
onlyDrawScreenSprites is never used anywhere.
| switch (eyeRef.Type) { | ||
| default: | ||
| _mobSightQuery.TryGetComponent(mob, out mobSight); | ||
| seeVis = mobSight?.SeeInvisibility ?? 127; | ||
| DrawNullEyeSprites(args, viewportSize, seeVis); | ||
| return; | ||
| case ClientObjectReference.RefType.Turf: | ||
| eyeCoords = new(new(eyeRef.TurfX, eyeRef.TurfY), new(eyeRef.TurfZ)); | ||
| _mobSightQuery.TryGetComponent(mob, out eyeSight); | ||
| break; | ||
| case ClientObjectReference.RefType.Entity: | ||
| var eyeUid = _entityManager.GetEntity(eyeRef.Entity); | ||
| if (!_xformQuery.TryGetComponent(eyeUid, out var eyeTransform)) | ||
| return; | ||
| eyeCoords = _transformSystem.GetMapCoordinates(eyeUid, eyeTransform); | ||
| _mobSightQuery.TryGetComponent(eyeUid, out eyeSight); | ||
| break; | ||
| } |
There was a problem hiding this comment.
Could this be turned into IsNullEye, EyeCoords, and Sight helper properties on DreamClientEye? It should be reachable from Draw()'s args.Viewport.Eye.
Adds a network message sent from the server to client to notify of mob/eye updates (currently, the client uses the attached entity which is ambiguous). I wasn't sure of a better way to accomplish this but am looking for feedback.
The client then uses this info to distinguish between eye/mob for context menu, drawing, and verbs.
Closes #1581
Closes #2081