DunnyOfPenwick wrote: ↑Mon Jun 14, 2021 5:04 pm
The spell requires appropriate material components to be in the character inventory to cast, but I could see no way to check for this until the entityEffect.Start() method was called. Adding a requirement check method to EntityEffect might help here; if requirements are not met, the spell is disabled in the spellbook.
You can check for the items at Start(). If the player isn't holding required items then output a message and End() the effect. If you don't want the player to burn their spellpoints by failing without materials, then you could refund cost of the effect back to spellpoints using FormulaHelper.CalculateEffectCosts() and casterEntity.IncreaseMagicka() before ending effect.
This also means other effects combined with this one will execute and cost as normal. You really don't want one effect blocking the whole spell. With up to 3x effects per spell, players have a habit of combining things in unusual ways. There's plenty of ways to get in trouble with this, I know this from experience.
DunnyOfPenwick wrote: ↑Mon Jun 14, 2021 5:04 pm
There is no atronach corresponding to the
Magic element type, but the button is always enabled by default in the SpellMaker.
Magic elements are for determining resistances when cast at another entity. Effect variants are for creating different styles of the same effect. For an Atronach summoning, limit this to ElementTypes.Magic in effect properties and use variant effects instead: "Create Atronach - Fire", "Create Atronach - Frost", etc.
DunnyOfPenwick wrote: ↑Mon Jun 14, 2021 5:04 pm
- By-touch/target-at-range assume the spell is a damaging spell requiring an enemy target. There might not be any payload as such attached to the spell. Also, I don't see any way to prevent a missile from being created when casting at-range spells. There might be cases (like Telekinesis) where a missile is undesirable.
Targeting by touch or by range are specifically for targeting other entities. If you don't want to target entities then use TargetTypes.CasterOnly in effect properties and target world objects however you want in the payload. Look to DispelUndead for an example that uses custom targeting. DetectTreasure is another effect that uses custom targeting for world objects instead of entities. These both use GetNearbyObjects() but you could do custom raycasts, etc. to target whatever you want based on how the effect is intended to work.
For a really novel example of a custom effect, check out my
Vanity Clone full moon easter egg. This effect creates a hovering paper doll, animates a swirling ball of custom missiles, and blasts foes (created by a quest) with those swirling missiles. It even heals the player if they stay near to the clone. You really can do almost anything you like with effects if you put your mind to it. Here's the effect
source code.
It mostly helps to just work within the framework and think about spells and effects in a Daggerfally way, rather than subvert something in a way it wasn't intended (e.g. elements for variants). And don't forget that players will combine effects in unexpected ways. The framework tries to coordinate everything but it's still possible to get in trouble when an effect takes over too much. Examples of this in core are Teleport and Open - they both like to have full control and don't play well with other effects.
Magicono43 wrote: ↑Sat Jun 19, 2021 1:43 am
My efforts so far have a summoned rat that is destroyed when the spell effect duration ends.
I'm not sure how that would happen. There's nothing inherently tying effect duration to created foes. If you want a summoned foe to persist, the effect itself doesn't even need a Duration component. Just create the foe in payload and end the effect.
GameObjectHelper.CreateFoeSpawner() is a good helper just to drop an enemy entity into the world. The spawner will self-destroy once all foes are placed. This doesn't need to be tied to the effect duration at all.