incompatibility with dynamic stealth
lag42 opened this issue ยท 19 comments
possessing an entity with dynamic stealth installed makes you appear as if you're still in soul mode even letting you fly and if you look down you can see what you've possessed
i've made an issue on dynamic stealth's repository too: Laike-Endaril/Dynamic-Stealth#27
Hey, I'm the DS dev. Just to keep all info in one place, I'll post in this thread.
I'll look into this after I'm done with one other issue.
Quite intriguing. It appears that the client never gets the information that you possessed something, but doesn't complain.
From what I've seen so far, I'm guessing a lot of dissolution's checks are client-side. If that's true, then this is most likely an issue of the possessed entity not existing client-side as soon as you possess something. DS alters the entity tracker to prevent unseen entities from existing client-side if they're not seen by the player (to prevent esper hacks, including minimaps and many others, as well as a few other reasons).
I've confirmed that disabling player senses in DS prevents the issue, though DS is much less interesting to play with player senses disabled. If you want to try that option, it's (server settings -> senses -> use player senses).
We should be able to fix this particular issue by making sure DS always allows the player to see the possessed entity. Not 100% sure on the details of that process yet. @Pyrofab Is the soul "riding" or "ridden by" the possessed entity, or neither (server-side)?
Did some tests; the possessed is neither riding nor ridden by the player. Making it so the player rides or is ridden by the entity might solve the issue, but I'm not sure if that would cause other issues on your end. I'll keep poking around a bit.
I tried setting the soul to ride the possessed, which resulted in rapid ascent to the heavens (the soul sat on the skeleton's shoulders and they both shot off into the sky like a rocket). This is probably due to the vanilla riding system physics having a disagreement with the possession system physics, and them leap-frogging each other into the sky.
In any case, it may be easier to do a check for possession from my end inside DS than to try to get dissolution to use the vanilla riding system, so I'll start looking into that approach.
@Pyrofab I need some way of getting the currently possessed entity (from outside of any event). Looking through your API, but haven't found anything yet. Is there a call I can make with the API to find the possessed entity of another entity?
That sound interesting...
Just finished that other issue. I'll start looking into this one.
Well, I have some good news, some bad news, and some more bad news XD
Good news: Got the capability working and made it so my sight algorithm always returns true for possessed entities, and confirmed it does so (simple printline showed while possessing zombie).
Bad news: This only fixes the visibility of the zombie, ie. the zombie is now visible at all times, but does not fix the flying; I can still fly my zombie through the skies (unless I reload the world, at which point it works normally).
Bad news 2: I hate forge capabilities. Not yours specifically, just all of them in general. Just had to get that off my chest.
I'll try triggering a flag from your API's Setup event to force visibility for a few ticks and see if that works. If not, maybe I'll try the same thing in one of the interact events.
Thank you for your time in helping solve this issue. Dissolution did use the vanilla riding system at one point, but that caused a host of other issues, so I am staying away from that option as much as possible.
My API is not extremely well organized, partly for retrocompatibility's sake. To find the possessor of an entity, you need to cast it to IPossessable. To find the entity currently possessed by a player, you need to get the IIncorporealHandler using Forge capabilities.
I seem to be on the wrong track for the possession sync issue, because forcing the entity tracker to always return true doesn't fix the issue:
public boolean isVisibleTo(EntityPlayerMP playerMP)
{
return true || Sight.canSee(playerMP, livingBase);
}
Unsure what the issue is here, as this should bypass all my systems as far as making things not exist on the client.
@SubscribeEvent
public static void worldLoad(WorldEvent.Load event) throws IllegalAccessException
{
World world = event.getWorld();
if (world instanceof WorldServer && serverSettings.senses.usePlayerSenses)
{
// worldServerEntityTrackerField.set(world, new EntityTrackerEdit((WorldServer) world));
}
}
Making sure I don't replace the entity tracker fixes it, so something unexpected is happening in there. I'll have to double check all differences between the vanilla trackers (since we're using 2 different forge versions; need to make sure forge didn't make any changes) and my own. This might take some time, but should hopefully lead to a solution.
Sorry for the large number of posts btw.
I've fixed the main issue, and possibly improved my general compat with other mods in the process, so that's nice. I have a couple more minor compat issues with dissolution that I can fix on my end, and one that may need to be fixed on your end, depending on your intended behavior of possessable entities that are not currently possessed.
So I have a question for you @Pyrofab...
Should possessable entities that are not currently possessed participate in combat, or should they be mindless shells? Also, any details on special cases, ie. player shell vs mob shell (I'm calling them shells for now; it's easier).
Possessable entities that are not possessed are just like the originals, and should behave exactly like them. Player shells are definitely mindless however.
Did the issue have something to do with Forge's sendToTracking
helper method ? I thought about that but you fixed it before I could hint you at it.
Alright, I've fixed everything I can from my end, which is almost everything (so I've closed the issue on my tracker).
The only thing left that I've noticed is an issue when you turn the camera so that a player shell comes into/leaves view repeatedly. Each time the shell is created client-side it seems to send an authorization request, presumably to get the player skin. Tbh I haven't dealt with player skins yet, but I do know that this does not happen when an actual player comes into/leaves view repeatedly, so there must be some other way to get the skin on there without all the requests.
In fact, I don't think the client even sends any requests at all for normal player entities; I think the skin might be passed from the server or something...not sure though.
In any case, the result is that the service quickly starts rejecting the requests due to frequency, at which point the skins fail to load and the game starts getting lag spikes upon each failed request (either main or render thread must be freezing until skin either loads or fails to load).
I used the skull way of getting the skin, so I'd blame Mojang. The lag spikes should only occur in offline games, as successful requests should be cached. I may try to use the player way, but I fear that may require a few hacks to make it work with absent players.
The issue was a combination of 2 bits of code, one in the entity tracker, and one in the entity tracker entry, both of which I had removed because I thought they'd be completely redundant due to some other changes I made. And in most cases they were, but not in this case due to the strict timing required:
Laike-Endaril/Dynamic-Stealth@ba87757
Laike-Endaril/Dynamic-Stealth@31c97f8
Anyway, at present, the player shell sprints away in fear if you attack it due to the AI from DS, so I'll make sure it doesn't execute for player shells. I also need to make one other minor change on my end, but I think that should be it. I'll post the results within a day.
PS. I wasn't sure if mob shells were supposed to be normal or not because they move super slow, unlike normal mobs. Not sure if that's intentional or not, but it happens with only dissolution installed.