Noober1 Posted January 10, 2021 Share Posted January 10, 2021 Hello! I've been working diligently on a mod that circling around 2 1h crossbows (the oldrim mod everyone by now has seen) and its coming along really well. I planning a D3 Demon Hunter style class and currently am working on a summon spell that summons a turret. When cast, the summon appears just find and turns to attack enemies but does not shoot any arrows or cast any spells. It has both arrows in inventory and spells added in spell list with plenty of magicka and skill offset to cast them. I looked into adding a script to force it to attack and it works, somewhat. What I have causes it to fire a firebolt at ANYONE (including the player) that is in range. I could live with that, though would optimally prefer it just attack hostiles, however the script stays in effect after the summon has disappeared/died. It just keeps firing off firebolts endlessly from the location the summon entered at. I used a 'Completed Script Example' from creation kit website and plugged in some of my Properties. Here's what I have so far.... Scriptname WHA_SentryCombatScript extends ObjectReference import UtilityActor Property PlayerREF AutoFloat Property xOffset Auto Float Property yOffset Auto Float Property zOffset AutoFloat Property RandomOffsetX AutoFloat Property RandomOffsetY Auto Float Property RandomOffsetZ Auto Float Property PulseRate = 1.0 Auto Float Property RandomRate Auto Activator Property TargetType Auto ObjectReference Property CurrentTarget AutoBool Property SpawnNode Auto Spell Property WHA_SentryFirebolt Auto FormList Property TargetTypeList AutoFloat Property SeekRange = 500.0 Auto Event OnUpdate() if !SpawnNode && !TargetTypeList && GetDistance(PlayerREF) < SeekRange CurrentTarget = PlayerREFelseif TargetTypeList CurrentTarget = Game.FindClosestReferenceOfAnyTypeInListfromRef(TargetTypeList, Self, SeekRange) endifif CurrentTarget WHA_SentryFirebolt.Cast(Self,CurrentTarget) endif RegisterForSingleUpdate(PulseRate + RandomFloat(0.0, RandomRate))EndEvent I recently got into scripting and am fairly new at it and would appreciate any help anyone could throw my way. Thanks Link to comment Share on other sites More sharing options...
Noober1 Posted January 10, 2021 Author Share Posted January 10, 2021 Actually this is my script...not the above reference which was missing an Event. Scriptname WHA_SentryCombatScript extends ObjectReference import UtilityActor Property PlayerREF AutoFloat Property xOffset Auto Float Property yOffset Auto Float Property zOffset AutoFloat Property RandomOffsetX AutoFloat Property RandomOffsetY Auto Float Property RandomOffsetZ Auto Float Property PulseRate = 1.0 Auto Float Property RandomRate Auto Activator Property TargetType Auto ObjectReference Property CurrentTarget AutoBool Property SpawnNode Auto Spell Property WHA_SentryFirebolt Auto FormList Property TargetTypeList AutoFloat Property SeekRange = 500.0 Auto Event OnInit() if CurrentTarget elseIf SpawnNode float newXOffset = XOffSet + RandomFloat(-RandomOffsetX, RandomOffsetX) float newYOffset = YOffSet + RandomFloat(-RandomOffsetY, RandomOffsetY) float newZOffset = ZOffSet + RandomFloat(-RandomOffsetZ, RandomOffsetZ) CurrentTarget = PlaceAtme(TargetType) CurrentTarget.MoveTo(Self, newXOffSet, newYOffSet, 500) endif RegisterForSingleUpdate(PulseRate)EndEvent Event OnUpdate() if !SpawnNode && !TargetTypeList && GetDistance(PlayerREF) < SeekRange CurrentTarget = PlayerREFelseif TargetTypeList CurrentTarget = Game.FindClosestReferenceOfAnyTypeInListfromRef(TargetTypeList, Self, SeekRange) endifif CurrentTarget WHA_SentryFirebolt.Cast(Self,CurrentTarget) endif RegisterForSingleUpdate(PulseRate + RandomFloat(0.0, RandomRate))EndEvent Link to comment Share on other sites More sharing options...
dylbill Posted January 10, 2021 Share Posted January 10, 2021 (edited) Okay, if you're not already, instead of using a spawn magic effect archetype, I would spawn your sentry with a script, use script archetype for your magic effect. That way you can set an owner in the sentry script and check if your target is hostile before casting. So the sentry script would look like this: Scriptname WHA_SentryCombatScript extends Actor import Utility Actor Property PlayerREF Auto Float Property xOffset Auto Float Property yOffset Auto Float Property zOffset Auto Float Property RandomOffsetX Auto Float Property RandomOffsetY Auto Float Property RandomOffsetZ Auto Float Property PulseRate = 1.0 Auto Float Property RandomRate Auto Activator Property TargetType Auto ObjectReference Property CurrentTarget Auto Bool Property SpawnNode Auto Spell Property WHA_SentryFirebolt Auto FormList Property TargetTypeList Auto Float Property SeekRange = 500.0 Auto Actor Property Owner Auto Hidden ;the actor that spawned this sentry Event OnInit() RegisterForSingleUpdate(PulseRate) EndEvent Event OnUpdate() Actor Target = Game.FindRandomActorFromRef(Self, SeekRange) if Target If Target.IsHostileToActor(Owner) ;only cast spell if hostile to owner. WHA_SentryFirebolt.Cast(Self,Target) Endif endif If Self.IsDead() == False RegisterForSingleUpdate(PulseRate + RandomFloat(0.0, RandomRate)) Endif EndEvent Then the script for you spawn magic effect would look something like this. Scriptname WHA_SentrySpawnScript extends ActiveMagicEffect ActorBase Property WHA_Sentry Auto Float Property Distance = 100.0 Auto Event OnEffectStart(Actor akTarget, Actor akCaster) Actor WHA_SentryRef = akCaster.PlaceActorAtMe(WHA_Sentry) ;place one sentry at caster (WHA_SentryRef as TWHA_SentryCombatScript).Owner = akCaster ;Set owner of sentry to the caster. EndEvent Hope that helps. Edited January 10, 2021 by dylbill Link to comment Share on other sites More sharing options...
Noober1 Posted January 10, 2021 Author Share Posted January 10, 2021 Thanks for taking the time man. I will check that when I get home Link to comment Share on other sites More sharing options...
Noober1 Posted January 10, 2021 Author Share Posted January 10, 2021 So this worked to keep the summon from attacking the player which is great, however I just need to add to the script to make it delete self or disappear after 60s. Link to comment Share on other sites More sharing options...
dylbill Posted January 11, 2021 Share Posted January 11, 2021 For that, you can add in a time check, like so: Scriptname WHA_SentryCombatScript extends Actor import Utility Actor Property PlayerREF Auto Float Property xOffset Auto Float Property yOffset Auto Float Property zOffset Auto Float Property RandomOffsetX Auto Float Property RandomOffsetY Auto Float Property RandomOffsetZ Auto Float Property PulseRate = 1.0 Auto Float Property RandomRate Auto Activator Property TargetType Auto ObjectReference Property CurrentTarget Auto Bool Property SpawnNode Auto Spell Property WHA_SentryFirebolt Auto FormList Property TargetTypeList Auto Float Property SeekRange = 500.0 Auto Actor Property Owner Auto Hidden ;the actor that spawned this sentry Float InitTime Event OnInit() InitTime = Game.GetRealHoursPassed() RegisterForSingleUpdate(PulseRate) EndEvent Event OnUpdate() Actor Target = Game.FindRandomActorFromRef(Self, SeekRange) if Target If Target.IsHostileToActor(Owner) ;only cast spell if hostile to owner. WHA_SentryFirebolt.Cast(Self,Target) Endif endif If ((Game.GetRealHoursPassed() - InitTime) > 0.016) || Self.IsDead() Self.Disable() Self.Delete() Else RegisterForSingleUpdate(PulseRate + RandomFloat(0.0, RandomRate)) Endif EndEvent Link to comment Share on other sites More sharing options...
Noober1 Posted January 11, 2021 Author Share Posted January 11, 2021 Is there a way to remove the spell from him? After it disappears, the spell still fires off from the location it was spawned at. Would I need the RemoveSpell from Actor Function?? Really Appreciate the help thus far. Link to comment Share on other sites More sharing options...
dylbill Posted January 11, 2021 Share Posted January 11, 2021 No problem, yes you can try RemoveSpell. Link to comment Share on other sites More sharing options...
Noober1 Posted January 11, 2021 Author Share Posted January 11, 2021 That seemed to have worked but I have another odd issue. The object (or actor) I am summoning/placingatme is actually is a Dwemer Trap bow, the ones that fire giant bolts at you. I used its nif as the model for the actor. Its animations do not play but I am completely fine with that since I am having a firebolt fling from it. However, the firebolt originates from the very bottom of the model/nif which pokes just below the ground and 9/10 times the firebolt is fired below ground and just hits the floor mesh and not the actor. Is there anyway to place the actor higher off the ground when it is summoned or have to firebolt shoot higher? I imagine the latter is far less likely as that most likely has to do with the nodes in the nif file itself. I tried to mess with the randomoffset z property but I didn't see any effect no matter how high or low I set the number. Link to comment Share on other sites More sharing options...
dylbill Posted January 11, 2021 Share Posted January 11, 2021 In the magic effect script you can try to use moveto: ActorBase Property WHA_Sentry Auto Float Property Distance = 100.0 Auto Event OnEffectStart(Actor akTarget, Actor akCaster) Actor WHA_SentryRef = akCaster.PlaceActorAtMe(WHA_Sentry) ;place one sentry at caster (WHA_SentryRef as TWHA_SentryCombatScript).Owner = akCaster ;Set owner of sentry to the caster. Float A = akCaster.GetAngleZ() Float XDist = Math.Sin(A) Float YDist = math.Cos(A) YDist *= Distance XDist *= Distance WHA_SentryRef.MoveTo(akCaster, XDist, YDist, 50, True) EndEventThat will move the sentry 100 units in front of you and 50 units higher. If it has collision though it will probably just fall to the floor. Link to comment Share on other sites More sharing options...
Recommended Posts