irswat Posted August 23, 2016 Share Posted August 23, 2016 (edited) I want to limit the number of childwisps a wisp mother can summon. Fought a wispmother the other day and she summoned like 30 wisps! Unacceptable. I also want to make a wispmother unique in appearance when she summons a child wisp by forcing her to wear a crown. I'm going to try my hand at this later. My initial thoughts:I'll add a counter so every time an orb/childwisp is summoned the counter will increment. Every time a childwisp dies the counter will decrement. Wispmother will only summon orb if number of childwisps < 9.My pseudocode. if (number of childwisps>=1) { int WispMotherID=self.GetFormID int CrownID=DLC1LD_AetherialCrown.GetFormID Game.WispMotherID.AddItem(CrownID, 1, true) WispMother.EquipItem(CrownID, true) } elseif (number of childwisps==0) //does Papyrus use == ? { if (Game.WispMotherID().IsEquipped(CrownID)) { WisMotherID.UnequipItem(CrownID, true) } }endif //do I need semi colons at the end of statements? Questions:Re: the use of self parameter, is this acceptable use of self, does Papyrus even use Self references, and can I use Self in this syntax in trying to obtain the FormID of any given WispMother?When using AddItem and EquipItem can i use FormID, or must I use BaseID?I don't want to alter the vanilla wispactorscript. How can I implement a script like this without altering the vanilla script?Please feel free to share your thoughts. Edited August 23, 2016 by irswat Link to comment Share on other sites More sharing options...
Caerulean Posted August 24, 2016 Share Posted August 24, 2016 I can't really help with the scripting part, but as someone who's tried to make use of the vanilla wispactorscript (which seems buggy as heck), I'll share my thoughts. One thing, the wispactorscript, which I believe was intended to create two Wispmother shades (when the Wispmother reaches the low health threshold), seems to have a high tendency to bug out and also create 'shades' of other actors involved in the fight, which often happen to be the Wispmother shades themselves and - apparently as you said - the wisp 'children'. In fortunate cases, only the Wispmother Fog FX, which is also added by the same script, gets mistakenly attached to a different actor. I've tried adding a condition on the Magic Effect (for a different actor which I wanted to use the script on) but to no avail. What can be tried is to create your own edition of the wispactorscript and add the necessary condition(s) or alterations there so that it won't replicate other actors. Then replace the script in the magic effect with yours. ^ I hope I made sense 'cause I wrote a lot of information in between sentences. lol Link to comment Share on other sites More sharing options...
irswat Posted August 24, 2016 Author Share Posted August 24, 2016 I got it working last night with help from family freddy. I may work on it some more tonight though. Have you ever seen a wispmother superior spawn like 30 wisps? Link to comment Share on other sites More sharing options...
Caerulean Posted August 25, 2016 Share Posted August 25, 2016 Not really, fortunately. I read somewhere that someone had a similar bug that caused the shades to replicate about that same number, I think. So far, I've only encountered such issues when I tried to make a similar Magic Effect with the wispactorscript. Have you tried testing again without your fix to see if the issue's consistent? Anyway, congrats on getting it to work. :) Link to comment Share on other sites More sharing options...
irswat Posted August 25, 2016 Author Share Posted August 25, 2016 (edited) Yes, the issue happens without the script. However I'm having some problems getting the script to work. Here is link: https://www.dropbox.com/s/2pmxpz1opvz0p0t/wispActorScript.psc?dl=0 Scriptname WispActorScript extends ActiveMagicEffect {Abilities and FX for Wisp/Glimmerwitch} ;======================================================================================; ; IMPORTS / ;=============/ import utility import form import debug ;======================================================================================; ; PROPERTIES / ;=============/ keyword property wispChild01 auto keyword property wispChild02 auto keyword property wispChild03 auto spell property wispBuff01 auto spell property wispBuff02 auto spell property wispBuff03 auto spell property Phase1ConcSpell auto {A long range concentration spell for phase #1} spell property Phase2ConcSpell auto {Shorter range spell for phase #2} actorBase property encWispShade auto VisualEffect Property WispFXAttachEffect Auto explosion property ExplosionIllusionLight01 auto Activator property AshPileObject auto {The object we use as a pile.} float property PhaseThreeHPPercent auto {At what % of HP should I spawn my dopplegangers?. DEFAULT: 0.2} Armor Property TGCrown01 Auto ;======================================================================================; ; VARIABLES / ;=============/ ObjectReference selfRef ; let's refer to the witchlights as "orbs" to avoid confusion. objectReference orb01 objectReference orb02 objectReference orb03 objectReference Shade01 objectReference Shade02 ;track number of living orb babies int liveLights = 3 ; have my FX been attached? bool bFX = FALSE ;counter for number of summoned wisps int WispChildCount = 0 int ShadeCount = 0 int WispCount = 0 int SpawnFlag = 0 ;======================================================================================; ; EVENTS / ;=============/ EVENT onLoad() trace("Wisp: Has Loaded 3D ("+selfRef+")") EVPall() endEVENT EVENT OnEffectStart(Actor Target, Actor Caster) trace("AbWisp Effect Start on: "+SelfRef+"") selfRef = caster if selfref.getLinkedRef() == NONE ; only attack FX at this point if I am not in an ambush link WispFXAttachEffect.Play(selfRef, -1) bFX = TRUE endif int RemainingWispChildren=(9-WispChildCount) if RemainingWispChildren>=3 orb01 = selfref.getLinkedRef(WispChild01) orb02 = selfRef.getLinkedRef(WispChild02) orb03 = selfRef.getLinkedRef(WispChild03) WispCount = 3 WispChildCount+=3 elseif RemainingWispChildren == 2 orb01 = selfref.getLinkedRef(WispChild01) orb02 = selfRef.getLinkedRef(WispChild02) WispCount = 2 WispChildCount+=2 elseif RemainingWispChildren==1 orb01 = selfref.getLinkedRef(WispChild01) WispCount = 1 WispChildCount+=1 endif EVPall() if phaseThreeHPpercent > 1.0 ; if we passed a high value, the user probably meant a whole number percentage like 30% phaseThreeHPpercent = phaseThreeHPpercent/100 endif ENDEVENT EVENT onGetup(ObjectReference akFurniture) if akFurniture == selfRef.getLinkedRef() && bFX == FALSE ; if I was in a furniture ambush, then add my FX when I leave it WispFXAttachEffect.Play(selfRef, -1) bFX = TRUE endif endEVENT Event OnCombatStateChanged(Actor victim, int aeCombatState) if aeCombatState != 0 ; 0 means not in combat, so non-zero means we entered combat ; debug.trace("Wisp began combat with "+victim+" ("+self+")") if aeCombatState == 1 if WispCount==1 (orb01 as actor).startCombat(victim) Debug.Notification("1 orb spawned") elseif WispCount == 2 (orb01 as actor).startCombat(victim) (orb02 as actor).startCombat(victim) Debug.Notification("2 orbs spawned") elseif WispCount == 3 (orb01 as actor).startCombat(victim) (orb02 as actor).startCombat(victim) (orb03 as actor).startCombat(victim) Debug.Notification("3 orbs spawned") endif ; Start listening for critically low HP registerforSingleupdate(1.0) endif endif endEVENT EVENT onActivate(objectReference actronaut) ; debug.trace("Wisp Activated") if actronaut == orb01 || orb02 || orb03 utility.wait(0.1) ; debug.trace("Actronaut was one of my orbs") liveLights -= 1 ; debug.trace("Livelights = "+livelights) if liveLights <= 0 ; debug.trace("All child lights dead for "+selfref) ;Variable07 sets up the berserk package/combat style (selfRef as actor).setActorValue("Variable07",1) ;also "eliminate" her ability to cast spells - take all her magicka away. trace("WISPS: move to combat phase 2") ; Take away her magicka (she'll regen) and shuffle her spell set (selfRef as actor).damageActorValue("Magicka", -((selfref as actor).getActorValue("Magicka"))) (selfref as actor).removeSpell(Phase1ConcSpell) (selfref as actor).addSpell(Phase2ConcSpell) endif endif endEVENT EVENT onUpdate() ; Check HP for Phase 3 Combat - Last ditch doppleganger attack! if (selfRef as actor).getActorValuePercentage("health") > phaseThreeHPpercent ; HP still high, so hold off. ;utility.wait(0.5) RegisterforSingleUpdate(0.5) else ; create my dopplegangers and unregister for update int RemainingShades=(3-ShadeCount) if RemainingShades>=2 Shade01 = (selfref as actor).placeAtMe(EncWispShade) Shade02 = (selfref as actor).placeAtMe(EncWispShade) Debug.Notification("2 shades spawned") ShadeCount=ShadeCount+2 elseif RemainingShades == 1 Shade01 = (selfref as actor).placeAtMe(EncWispShade) ShadeCount=ShadeCount+1 Debug.Notification("1 shade spawned") endif ;Set AV06 to 1 as a flag for being in this state (used in Frostmere Crypt) (selfref as actor).SetAV("Variable06", 1) ; Dump the orbs. (orb01 as actor).kill() (orb02 as actor).kill() (orb03 as actor).kill() ; restore her longer-range spell (selfref as actor).addSpell(Phase1ConcSpell) endif bool IsOrb01Dead=(orb01 as actor).IsDead() bool IsOrb02Dead=(orb02 as actor).IsDead() bool IsOrb03Dead=(orb03 as actor).IsDead() if (IsOrb01Dead==true) WispChildCount=WispChildCount-1 Debug.Notification("Wisp Child has died") endif if (IsOrb02Dead==true) WispChildCount=WispChildCount-1 Debug.Notification("Wisp Child has died") endif if (IsOrb03Dead==true) WispChildCount=WispChildCount-1 Debug.Notification("Wisp Child has died") endif bool IsShade01Dead=(Shade01 as actor).IsDead() bool IsShade02Dead=(Shade02 as actor).IsDead() if (IsShade01Dead==true) ShadeCount=ShadeCount-1 Debug.Notification("Shade has died") endif if (IsShade02Dead==true) ShadeCount=ShadeCount-1 Debug.Notification("Shade has died") endif bool CrownofPowerStatus=(selfRef as actor).IsEquipped(TGCrown01) if (((WispChildCount >= 1)||(ShadeCount >= 1)) && (CrownofPowerStatus==false)) (selfRef as actor).AddItem(TGCrown01, 1, true) (selfRef as actor).EquipItem(TGCrown01, true) Debug.Notification("Diadem of the Wispmother Superior equipped") elseif (((WispChildCount == 0)&&(ShadeCount == 0)) && (CrownofPowerStatus==true)) (selfRef as actor).UnequipItem(TGCrown01, true) CrownofPowerStatus = false Debug.Notification("Diadem of the Wispmother Superior unequipped") endif endEVENT EVENT OnDying(Actor akKiller) ; Effects automatically finish onDeath so use this EVENT hook instead trace("Actor has died: "+selfref) (selfRef as actor).SetCriticalStage((selfRef as actor).CritStage_DisintegrateStart) WispFXAttachEffect.Stop(selfRef) utility.wait(0.90) selfRef.placeatme(ExplosionIllusionLight01) (selfRef as actor).AttachAshPile(AshPileObject) ; pause a second before killing inheritors - I've seen massive damage skip over this utility.wait(0.5) (orb01 as actor).kill() (orb02 as actor).kill() (orb03 as actor).kill() (Shade01 as actor).kill() (Shade02 as actor).kill() (selfRef as actor).SetCriticalStage((selfRef as actor).CritStage_DisintegrateEnd) WispCount=0 ShadeCount=0 ENDEVENT FUNCTION EVPall() trace("Sending EVP to self and witchlight children ("+selfRef+")") trace("Witchlights are the Following:") trace("--------------------------------") trace(orb01) trace(orb02) trace(orb03) trace("--------------------------------") (orb01 as actor).evaluatePackage() (orb02 as actor).evaluatePackage() (orb03 as actor).evaluatePackage() endFUNCTION Edited August 26, 2016 by irswat Link to comment Share on other sites More sharing options...
irswat Posted August 25, 2016 Author Share Posted August 25, 2016 (edited) random question: in c++ I can use iterators like X-=1 and X++, for x=x-1 and x=x+1 respectively. Does papyrus recognize these same iterators? Edited August 26, 2016 by irswat Link to comment Share on other sites More sharing options...
Recommended Posts