Attach Gameobject Entity To Spell Bundle, Chicken Before The Egg Problem?

Discuss modding questions and implementation details.
Post Reply
User avatar
Magicono43
Posts: 673
Joined: Tue Nov 06, 2018 7:06 am

Attach Gameobject Entity To Spell Bundle, Chicken Before The Egg Problem?

Post by Magicono43 »

Alright, so I'm making this post because after many hours of just thinking of how I might do this particular implementation, it's starting to feel like I'm trying to fix a square peg through a round hole.

Basically I'm working on a custom spell effect that summons a temporary enemy entity that is set to the team of the player (hopefully set to the team of the caster eventually if I can get this into the spell table of other entities). Now I got the basic function of this spell working with only a slight bit of hacking involved with adding a custom variable to the "EntityEffectManager" script. The specified enemy gets created when the spell is cast using the "CreateFoeGameObjects" method, the basic requirements are done to make this an active gameobject as the method comments say you need to do, and store a reference of the enemy gameobject that was created in my custom variable I mentioned for later use, also the player is informed in a text pop-up of what they just summoned.

Currently, I have it so when the duration of the spell effect wears off the attached gameobject (the summoned entity) is destroyed from the scene and the custom variable that was storing their gameobject reference is set to null, still have to work out how I will make it so the spell effect will end early when the attached entity dies through any means and be deleted from the scene in the same way before they can leave a corpse and such, but I'll deal with that logic later, likely have to make it a constant effect that checks their health or something.

Now, the issue I'm having is that I would like to somehow attach this gameobject reference of the summoned entity to the spell bundle itself, that way I will have an individual instance anytime this spell is cast that can keep track of the respective summoned entities they are associated with. The problem though is that this is sort of a chicken before the egg situation, since the spell bundle is created before the "start" part of a spell is ever ran, and the gameobject entity is created during the "start" of the spell. So I'd like to know if there could be some way I could do this where I can somehow associate the summoned enemy with the spell bundle it is created by, but after all my thinking I still can't figure out a way that I could do this, so I figure I may as well post this here and see if anyone is more clever than me. I'm working with a separate DFU fork btw, so altering code and scripts is entirely within reason here.

Here is a screenshot of the main working part of the spell effect if that might be helpful to get a better idea what is going on.
Capture.PNG
Capture.PNG (59.59 KiB) Viewed 635 times
Here is that screenshot in text form as well.

Code: Select all

void StartSummon() // Change this for summon behavior
        {
            // Get peered entity gameobject
            DaggerfallEntityBehaviour entityBehaviour = GetPeeredEntityBehaviour(manager);
            if (!entityBehaviour)
                return;

            if (manager.AttachedSummonedEntity != null) // This seems to have worked for the one problem at least, that's good.
                return;

            // Part where monster ally is actually created
            UnityEngine.GameObject player = GameManager.Instance.PlayerObject;
            UnityEngine.GameObject[] mobile = DaggerfallWorkshop.Utility.GameObjectHelper.CreateFoeGameObjects(player.transform.position + player.transform.forward * 2, (MobileTypes)(int)monsterCareer, 1, MobileReactions.Hostile, null, true);

            DaggerfallEntityBehaviour behaviour = mobile[0].GetComponent<DaggerfallEntityBehaviour>();
            EnemyEntity entity = behaviour.Entity as EnemyEntity;

            //mobile[0].transform.LookAt(mobile[0].transform.position + (mobile[0].transform.position - player.transform.position));
            mobile[0].SetActive(true);
            manager.AttachedSummonedEntity = mobile[0];

            // Output "You Summoned Something" if the host manager is player
            if (awakeAlert && manager.EntityBehaviour == GameManager.Instance.PlayerEntityBehaviour)
            {
                DaggerfallUI.AddHUDText(string.Format("You Summon A {0}", (MobileTypes)monsterCareer), 1.5f);
                awakeAlert = false;
            }
        }

        void EndSummon() // Change this for summon behavior
        {
            // Get peered entity gameobject
            DaggerfallEntityBehaviour entityBehaviour = GetPeeredEntityBehaviour(manager);
            if (!entityBehaviour)
                return;

            UnityEngine.GameObject summonedEntity = manager.AttachedSummonedEntity;
            UnityEngine.GameObject.Destroy(summonedEntity);
            manager.AttachedSummonedEntity = null;
            ResignAsIncumbent();
        }
Thanks for any help, I'm still sort of scratching my head on this one.

User avatar
DunnyOfPenwick
Posts: 57
Joined: Wed Apr 14, 2021 1:58 am
Location: Southeast US

Re: Attach Gameobject Entity To Spell Bundle, Chicken Before The Egg Problem?

Post by DunnyOfPenwick »

A new EntityEffect is instantiated every time you cast a spell.
You can just store the summoned creature GameObject in your EntityEffect.

I suggest putting the code to destroy the GameObject in your EntityEffect End() method.

As far as handling premature death, you can register an event handler on the entity like so:
entity.OnDeath += Entity_OnDeathHandler;

Then in your Entity_OnDeathHandler you can call your End() method to destroy the GameObject
and set RoundsRemaining = 0..

I am about to publish my Illusory Decoy spell mod in the next day or so that does these things.
I'll put the source code in my github repo.

User avatar
Magicono43
Posts: 673
Joined: Tue Nov 06, 2018 7:06 am

Re: Attach Gameobject Entity To Spell Bundle, Chicken Before The Egg Problem?

Post by Magicono43 »

DunnyOfPenwick wrote: Tue Jun 22, 2021 6:10 pm A new EntityEffect is instantiated every time you cast a spell.
You can just store the summoned creature GameObject in your EntityEffect.

I suggest putting the code to destroy the GameObject in your EntityEffect End() method.

As far as handling premature death, you can register an event handler on the entity like so:
entity.OnDeath += Entity_OnDeathHandler;

Then in your Entity_OnDeathHandler you can call your End() method to destroy the GameObject
and set RoundsRemaining = 0..

I am about to publish my Illusory Decoy spell mod in the next day or so that does these things.
I'll put the source code in my github repo.
Thanks a lot for the answer, I'll have to give this a try and see what happens. Not sure how you know all this stuff, but I'm certainly somewhat lost in exactly how to work with this spell code and Unity gameobjects and such, lol.

User avatar
DunnyOfPenwick
Posts: 57
Joined: Wed Apr 14, 2021 1:58 am
Location: Southeast US

Re: Attach Gameobject Entity To Spell Bundle, Chicken Before The Egg Problem?

Post by DunnyOfPenwick »

I've written some mods over the past 3 months or so and had to pore over a lot of DFUnity code.
I learned a good bit about Unity as well. Never messed with it before.

User avatar
Magicono43
Posts: 673
Joined: Tue Nov 06, 2018 7:06 am

Re: Attach Gameobject Entity To Spell Bundle, Chicken Before The Egg Problem?

Post by Magicono43 »

So the OnDeath event handler method you mentioned works perfectly, I do wonder if I should unsubscribe to the event as well when the spell ends? I know I have done this before in my other mods where I don't ever explicitly unsubscribe from an event handler, but not sure if that creates garbage overtime or something.

Either way, thanks for that help with the OnDeath part, I thought it was going to be a lot more complex than that. So far the most buggy part of the spell effect is when you mix it in a bundle with other summon effects for different enemy types, but then again the multi-spell effect bundles always are a bit weird depending on the spell effects used together, lol.

User avatar
DunnyOfPenwick
Posts: 57
Joined: Wed Apr 14, 2021 1:58 am
Location: Southeast US

Re: Attach Gameobject Entity To Spell Bundle, Chicken Before The Egg Problem?

Post by DunnyOfPenwick »

I'm not 100% sure about C# event resource handling, my background is more Java/C related.

To be on the safe side, deregister the event handler in your End() method and make sure all pathways result in the End() method being called as it should be.

Another thing to keep in mind is save/load mechanics, if you have any.

User avatar
DunnyOfPenwick
Posts: 57
Joined: Wed Apr 14, 2021 1:58 am
Location: Southeast US

Re: Attach Gameobject Entity To Spell Bundle, Chicken Before The Egg Problem?

Post by DunnyOfPenwick »

Well, I just remembered, the event is located in the Entity, so when the entity gets destroyed the event handler stuff should get destroyed with it.

User avatar
Magicono43
Posts: 673
Joined: Tue Nov 06, 2018 7:06 am

Re: Attach Gameobject Entity To Spell Bundle, Chicken Before The Egg Problem?

Post by Magicono43 »

Oh alright, that's probably correct, no reason to complicate things if the destroyed object will just deal with that anyway.

The way I have it now (I have not tested it though) I would expect the summon to be possibly brought back with full-health whenever a save is loaded, but not sure, have not tested saving/loading yet while the spell is currently active.

I'd like to get the rest of the spell variants for the other monsters in there just for the sake of it, as well as add some restrictions for the monsters such as the water based ones so the caster can't use those summons when they are not currently submerged.

After adding some of that hopefully I can start working on the main thing I wanted to work on involving this summon mechanic, that being actual proper AI where allied entities will actually at least follower/path toward the "leader" or summoner instead of just standing like a watch-dog at the place they were spawned/summoned originally. That's outside the scope of this thread though, just day-dreaming at this rate, lol.

Thanks for the help jogging my brain once again, I was stuck on that gameobject associating to the spell effect for WAY too long the past 2 days or so, lol.

User avatar
DunnyOfPenwick
Posts: 57
Joined: Wed Apr 14, 2021 1:58 am
Location: Southeast US

Re: Attach Gameobject Entity To Spell Bundle, Chicken Before The Egg Problem?

Post by DunnyOfPenwick »

" ...as well as add some restrictions for the monsters such as the water based ones so the caster can't use those summons when they are not currently submerged."

That reminds me, I originally prevented Create Atronach from creating fire atronachs when underwater, but it looks like I somehow deleted it in my last code rewrite. Thanks for the reminder!

Post Reply