[ANGRY PIXEL] The Betweenlands

[ANGRY PIXEL] The Betweenlands

24M Downloads

Dynamic Stealth compat (attack target null check)

Laike-Endaril opened this issue ยท 9 comments

commented

Betweenlands version: 3.4.8

Forge version: 14.23.5.2768

Singleplayer or Multiplayer: Both; regular forge server

Installed mods:

Betweenlands 3.4.8
Dynamic Stealth 1.12.2.076
Fantastic Lib 1.12.2.012

Link to full crash log

https://pastebin.com/Ui7GNyVY

Description of the problem

How to reproduce:

  1. Create a new world in creative mode
  2. Summon a bunch of silt crabs
  3. Build some obstacles to block LOS (I used 2-block high spikes of dirt)
  4. Switch to survival mode and run around the obstacles

Expected result:

Don't crash

Actual result:

Crash

Details:

This is a common compat issue between DS and AI tasks which don't do a null check on the attack target before accessing it.

Normally a null check on the attack target is not necessary during updateTask() because it usually doesn't change between shouldExecute()/shouldContinueExecuting() and updateTask(), but that's just the "normal circumstances".

Dynamic Stealth enforces stealth by setting the attack target to null, and due to the way MC's AI task handling works, this can happen between the methods I mentioned above. I have a filter for this kind of thing that I can add AI tasks to in order to "fix" them, but it's not very efficient at runtime, so I'm here to request same-method null checks in AI tasks, as it is far more efficient at runtime than my little hack is (and a bit more reliable).

For now, I'll try to go through AI tasks and add them to my filter when I get a chance. If you do end up adding null checks, poke me and I can remove the filter entries to recover the bit of performance loss.

commented

I went through all the AI tasks and checked for incompatible absence of null checks (actually, most of the AI tasks are handling null attack targets just fine already).

Here is a list of the offenders (may need to read the next few lines of code for each to see the usage):

EntityLivingBase target = this.attacker.getAttackTarget();

EntityLivingBase entitylivingbase = ash_sprite.getAttackTarget();

EntityLivingBase target = this.pyrad.getAttackTarget();

this.sludge.faceEntity(this.sludge.getAttackTarget(), 10.0F, 10.0F);

if(!this.stayInRange || this.entity.getAttackTarget().getDistanceSqToCenter(pos) <= this.maxRangeSq) {

That last one (the tree face) references attack target several times after that as well (no null checks). I'll probably release a new version of DS today with these in the filter as a temporary workaround (see last part of my previous post)

commented

Will look into it, thanks. ๐Ÿ‘

commented

You can grab the latest dev build of the mainline containing the fix here: https://github.com/Angry-Pixel/The-Betweenlands-Development-Builds/releases/tag/dev-1.12-fixes-1716-16.06.2019. If there are still problems please let me know. If it's fixed I can release a new build.

commented

Thanks for the quick response, I'll grab it and take a look

commented

All the ones I linked seem to be fixed, but I did find one more I missed on the first pass. Hopefully this is the last of it:

EntityLivingBase entitylivingbase = ashSprite.getAttackTarget();

commented

Looks like you're right; a null check in shouldExecute() should be fine for startExecuting(), just not for updateTask(). For some reason I thought it queued and iterated for both. That last one can be safely reverted, if you like.

This one is also in startExecuting(), if you want to revert things:

Thanks for your quick work! I'll keep an eye out for curseforge releases to The Betweenlands and remove filter entries on my end when these are in a release

commented

๐Ÿ‘

commented

Release is waiting to be approved on Curseforge

commented

Ok, will do. I don't think it actually matters in startExecuting() though because that is called right after shouldExecute() and there's no way for AI tasks to reset the attack target between those calls.