Interkarma / daggerfall-unity

Open source recreation of Daggerfall in the Unity engine
http://www.dfworkshop.net
MIT License
2.67k stars 326 forks source link

Preserve enemy orientation when hit by the Wabbajack #2666

Open petchema opened 1 month ago

petchema commented 1 month ago

A new gameObject is actually created for the transmuted enemy, facing north. Keep the orientation of the replaced gameObject instead.

Test: you can give yourself the Wabbajack by typing "addArtifact 6" in the console

Forums: https://forums.dfworkshop.net/viewtopic.php?t=6709&sid=e5aade01a84f5052bc8b32e13e7ee934

petchema commented 1 month ago

I think it's classic behavior, I haven't tried getting the Wabbajack in classic, but it seems @numidium did years ago: https://www.youtube.com/watch?v=exj1xrX_vtU&t=296s most enemies are hit facing the player and keep facing the player, but once around 4:56 he hits a guard in the back and he transforms in a fire atronach, apparently facing the same direction

KABoissonneault commented 1 month ago

Yeah no worries, it's not an area where I expect classic consistency. Let's just do what seems more natural, your change should be good

petchema commented 1 month ago

Noticed something else funky in the code making sure the enemyType changed:

                if ((int)enemyType == enemy.CareerIndex)
                    enemyType = (MobileTypes)(((int)enemyType + 1) % careerIDs.Length);

If the goal is to pick the next existing MobileType, then modulo should be MobileTypes.Length. But it would mean the Wabbajack can generate a monster type that's not in careerIDs, which looks suspiciously undesirable.

And if the goal was to pick the next MobileType in careerIDs array, then the code is totally incorrect, that's the array index that should be incremented, not the value taken from the array (also it would put a higher probability to generate one MobileType than others, for no good reason).

So I suggest replacing this code by a simple retry,

                MobileTypes enemyType;
                do {
                    enemyType = careerIDs[Random.Range(0, careerIDs.Length)];
                } while ((int)enemyType == enemy.CareerIndex);

which is much simpler than other correct alternatives like

                int oldCareerPos = System.Array.IndexOf(careerIDs, (MobileTypes)enemy.CareerIndex);
                int newCareerPos;
                if (oldCareerPos == -1)
                {
                    newCareerPos = Random.Range(0, careerIDs.Length);
                }
                else
                {
                     newCareerPos = Random.Range(0, careerIDs.Length - 1);
                     if (newCareerPos >= oldCareerPos)
                        newCareerPos++;

                }
                MobileTypes enemyType = careerIDs[newCareerPos];