maxarturo Posted December 27, 2020 Share Posted December 27, 2020 (edited) Hi all. Today i looked at a default vanilla script that i'm using (i've never looked at it in the past) and i noticed that it uses "OnLoad()" to add the 'Ghost Ab Spell', and i'm wondering 2 things: 1) The "OnLoad()" will add the Ab spell multiple times, won't this cause stacking of the spell ?. * The script doesn't have a function to remove the Ab spell. Default Vanilla Ghost Script: Scriptname defaultGhostScript extends Actor EFFECTSHADER PROPERTY pGhostFXShader AUTO FORMLIST PROPERTY pDefaultGhostWeaponFlickerList AUTO CONTAINER PROPERTY pDefaultGhostCorpse AUTO EXPLOSION PROPERTY pdefaultGhostDeathExplosion AUTO LEVELEDITEM PROPERTY pdefaultGhostLeveledList AUTO BOOL PROPERTY bdefaultLoot=FALSE AUTO {mark true if you want the default ghost loot and not the NPCs} BOOL PROPERTY bflicker=FALSE AUTO {don't use this yet} SPELL PROPERTY pGhostAbilityNew AUTO SPELL PROPERTY pGhostResistsAbility AUTO ; //any perks you want to add PERK PROPERTY pGhostHalfDamagePerk AUTO BOOL PROPERTY bFade=FALSE AUTO {makes the ghost fade out instead of explode} ; //make sure only one flash is active BOOL bFlash=FALSE ; //the person who caused the ghost to flash ACTOR target ; ////////// ; //LOOT PILE VARIABLES ; ////////// ; ////////// ; //ASH PILE VARIABLES ; ////////// float property fDelay = 0.75 auto {time to wait before Spawning Ash Pile} float property fDelayEnd = 1.65 auto {time to wait before Removing Base Actor} float property ShaderDuration = 0.00 auto {Duration of Effect Shader.} Activator property pDefaultAshPileGhost auto {The object we use as a pile.} Bool property bSetAlphaZero = True auto {The Effect Shader we want.} FormList Property pDisintegrationMainImmunityList auto {If the target is in this list, they will not be disintegrated.} EFFECTSHADER PROPERTY pGhostDeathFXShader AUTO {the shader to play while dying} race VictimRace bool TargetIsImmune = True ; /////////// ; //ONLOAD ; /////////// EVENT onLoad() ; // add on the abilities SELF.addSpell(pGhostAbilityNew) SELF.addSpell(pGhostResistsAbility) ; // for some reason this makes ghostFlash work better IF(bFlicker) ghostFlash(1) ENDIF ENDEVENT ; ///////// ; //ONHIT: When the ghost is hit, if the player isnt using the proper weapon, have them fade ; ///////// EVENT onHIT(OBJECTREFERENCE akAggressor, FORM akSource, Projectile akProjectile, BOOL abPowerAttack, BOOL abSneakAttack, BOOL abBashAttack, BOOL abHitBlocked) ; //if we're supposed to flicker and we're hit by a weapon without turn and we're not blocked, flash IF(bflicker && !pDefaultGhostWeaponFlickerList.hasForm(akSource) && !abHitBlocked && !bFlash) bFlash = TRUE target = akAggressor as ACTOR ghostFlash(3) ENDIF ENDEVENT ; ///////// ; //GHOSTFLASH: play this to flash the ghost when hit or attacking ; // ; //float time: the amount of time to be invincible ; ///////// FUNCTION ghostFlash(FLOAT time) ; //stop the effect to keep the particles pGhostFXShader.stop(SELF) SELF.setGhost() ; //be invincible for x seconds utility.wait(time) ; //return the ghost to normal SELF.setGhost(FALSE) SELF.setAlpha(0.3) pGhostFXShader.play(SELF) bFlash = FALSE ENDFUNCTION ; ///////// ; //ONDYING: On dying play an explosion to mask the ghost vanishing and being replaced by his corpse ; ///////// EVENT onDYING(ACTOR killer) IF(bFade) SELF.blockActivation(TRUE) disable(1) ELSE ; //check to see if the target is in the immunity list IF(pDisintegrationMainImmunityList == none) TargetIsImmune = False ELSE ActorBase VictimBase = SELF.GetBaseObject() as ActorBase VictimRace = VictimBase.GetRace() IF(pDisintegrationMainImmunityList.hasform(VictimRace) || pDisintegrationMainImmunityList.hasform(VictimBase)) TargetIsImmune = True ELSE TargetIsImmune = False ENDIF ENDIF ; //if the target is not immune, disintegrate them IF(TargetIsImmune == False) ; debug.trace("victim just died") SELF.SetCriticalStage(SELF.CritStage_DisintegrateStart) IF(pGhostDeathFXShader != none) pGhostDeathFXShader.play(SELF,ShaderDuration) ENDIF SELF.SetAlpha (0.0,True) ; //attach the ash pile SELF.AttachAshPile(pDefaultAshPileGhost) IF(bdefaultLoot) SELF.RemoveAllItems() SELF.addItem(pdefaultGhostLeveledList) ENDIF utility.wait(fDelayEnd) IF(pGhostDeathFXShader != none) pGhostDeathFXShader.stop(SELF) ENDIF IF(bSetAlphaZero == True) SELF.SetAlpha (0.0,True) ENDIF SELF.SetCriticalStage(SELF.CritStage_DisintegrateEnd) ENDIF ENDIF ENDEVENT 2) Why the game's developers didn't just add the Ab spell directly to the npc but they choose instead to add it by script. Is this one more Bethesda f*** up?. * I think i need to remove completely this default vanilla script from my mod as i've done with countless other. Thank you. Edited December 27, 2020 by maxarturo Link to comment Share on other sites More sharing options...
dylbill Posted December 27, 2020 Share Posted December 27, 2020 I don't use default scripts ever, I just prefer to write my own so they can be tailored to the mod. Using addspell for abilities won't stack. If the npc already has the ability nothing happens. You can use the check if Npc.HasSpell(MySpell) if you're worried about it though. Using MySpell.Cast(NPC) can stack effects though. Link to comment Share on other sites More sharing options...
maxarturo Posted December 27, 2020 Author Share Posted December 27, 2020 (edited) Hey dylbill. I don't actually worry about issues since i've tested them to death, plus in every test i make for something else i run into those mod's ghost npcs. * Plus i removed the vanilla script and add the Ab directly to the actors. I made this post because i cannot understand why the game developers didn't add the 'Ghost Ab' directly to the vanilla ghost actors and they use scripted means, there must be a reason behind it... i refuse to think that they were so stupid. * But in the other hand i've run into so many vanilla F*** UPS... Anyway, have a pleasant day. Edited December 27, 2020 by maxarturo Link to comment Share on other sites More sharing options...
ReDragon2013 Posted December 27, 2020 Share Posted December 27, 2020 (edited) In case the ability (or magic effect inside) have a condition like this Is3DLoaded == 1.00, imho the ability should be removed from actor. If not as dylbill has written: "If the npc already has the ability nothing happens." an ability is only a spell. You asked: "Why the game's developers didn't just add the Ab spell directly to the npc but they choose instead to add it by script." .. "there must be a reason behind it.."Probably it was convenience, because they needed a cleanup routine for ghosts by dying. And do not forget the script is prepared for using a special perk "pGhostHalfDamagePerk". the vanilla script could have error as follow: [08/08/2015 - 02:03:55AM] error: Cannot add a None spell to the actorstack: [ (000725F7)].defaultGhostScript.AddSpell() - "<native>" Line ? [ (000725F7)].defaultGhostScript.OnLoad() - "defaultGhostScript.psc" Line 230[08/08/2015 - 02:03:55AM] error: Cannot add a None spell to the actorstack: [ (000725F7)].defaultGhostScript.AddSpell() - "<native>" Line ? [ (000725F7)].defaultGhostScript.OnLoad() - "defaultGhostScript.psc" Line 231 I rewrote the script a bit and add some commentsdefaultGhostScript Scriptname defaultGhostScript extends Actor {v1.4a ReDragon 2020} FormList PROPERTY pDefaultGhostWeaponFlickerList auto Container PROPERTY pDefaultGhostCorpse auto ; UnUSED LeveledItem PROPERTY pdefaultGhostLeveledList auto EffectShader PROPERTY pGhostFXShader auto Explosion PROPERTY pdefaultGhostDeathExplosion auto Perk PROPERTY pGhostHalfDamagePerk auto ; UnUSED, placeholder for a perk you want to add Spell PROPERTY pGhostAbilityNew auto Spell PROPERTY pGhostResistsAbility auto Bool PROPERTY bflicker = False auto ; Do not use this yet !!! Bool PROPERTY bdefaultLoot = False auto ; mark true if you want the default ghost loot and not the NPCs Bool PROPERTY bFade = False auto ; makes the ghost fade out instead of explode Bool bFlash ; [default=False], make sure only one flash is active ;Actor target ; *) UnUSED, the person who caused the ghost to flash ; ASH PILE Properties and Vars for dying ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FormList PROPERTY pDisintegrationMainImmunityList auto ; If the target is in this list, they will not be disintegrated. Activator PROPERTY pDefaultAshPileGhost auto ; The object we use as a pile. EffectShader PROPERTY pGhostDeathFXShader auto ; the shader to play while dying Bool PROPERTY bSetAlphaZero = TRUE auto ; The Effect Shader we want. Float PROPERTY fDelay = 0.75 auto ; time to wait before Spawning Ash Pile Float PROPERTY fDelayEnd = 1.65 auto ; time to wait before Removing Base Actor Float PROPERTY ShaderDuration = 0.00 auto ; Duration of Effect Shader. ;Race VictimRace ; UnUSED ;Bool TargetIsImmune = TRUE ; UnUSED, code optimization ; -- FUNCTION -- ;------------------------------ FUNCTION ghostFlash(Float time) ;------------------------------ ; play this to flash the ghost when hit or attacking ; "The effects created by play() function stack, so using multiple times without stopping may cause frame rate issues." pGhostFXShader.Stop(self) ; stop self.SetGhost(TRUE) ; switch on status ghost Utility.Wait(time) ; amount of time for actor to be invincible self.SetGhost(False) ; switch off status ghost self.SetAlpha(0.3) pGhostFXShader.Play(self) ; play bFlash = False ENDFUNCTION ; -- EVENTs -- 3 ; https://www.creationkit.com/index.php?title=AddSpell_-_Actor ; bool Function AddSpell(Spell akSpell, bool abVerbose = true) native EVENT OnLoad() IF ( pGhostAbilityNew ) self.AddSpell(pGhostAbilityNew) ; (error line 230) ENDIF IF ( pGhostResistsAbility ) self.AddSpell(pGhostResistsAbility) ; (error line 231) ENDIF IF ( bFlicker ) ghostFlash(1.0) ENDIF ENDEVENT EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProj, Bool b1, Bool b2, Bool b3, Bool b4) ; When the ghost is hit and the player is not using the proper weapon, fade them out only IF ( b4 ) RETURN ; - STOP - hit was blocked ENDIF ;--------------------- by default "bFlicker is False", that means OnHit() event has no action inside IF ( bFlicker ) IF ( bFlash ) RETURN ; - STOP - flash action is still running ENDIF ; ---------------------- IF pDefaultGhostWeaponFlickerList.HasForm(akSource) RETURN ; - STOP - do no flash caused by weapon hit ENDIF ; ---------------------- bFlash = TRUE ;target = akAggressor as Actor ; *) ??? see script variable on top ghostFlash(3.0) ENDIF ENDEVENT ;========================== state Done ; busy with disintegration process ;========= EVENT OnLoad() ENDEVENT EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProj, Bool b1, Bool b2, Bool b3, Bool b4) ENDEVENT ;======= endState EVENT OnDying(Actor akKiller) ; its a bit different to script "defaultGhostScriptRefAlias.psc" IF ( bFade ) self.BlockActivation(TRUE) self.Disable(TRUE) RETURN ; - STOP - ENDIF ;--------------------- IF ( pDisintegrationMainImmunityList ) actorBase AB = self.GetBaseObject() as ActorBase ; AB = VictimeBase IF pDisintegrationMainImmunityList.HasForm( AB.GetRace() ) RETURN ; - STOP - ENDIF ; ---------------------- IF pDisintegrationMainImmunityList.HasForm(AB) RETURN ; - STOP - ENDIF ; ---------------------- ENDIF gotoState("Done") ; ### STATE ### pGhostFXShader.Stop(self) ; *** added by ReDragon 2020 *** self.SetCriticalStage( self.CritStage_DisintegrateStart ) ; Ashpile started ; --------------------------------------------------------- IF ( pGhostDeathFXShader ) pGhostDeathFXShader.Play(self, ShaderDuration) ENDIF self.SetAlpha(0.0, TRUE) self.AttachAshPile(pDefaultAshPileGhost) IF ( bdefaultLoot ) ; == TRUE self.RemoveAllItems() self.AddItem(pdefaultGhostLeveledList) ENDIF Utility.Wait(fDelayEnd) ; by default, wait here for 1.65 sec IF ( pGhostDeathFXShader ) pGhostDeathFXShader.Stop(self) ENDIF IF ( bSetAlphaZero ) ; == TRUE self.SetAlpha(0.0, TRUE) ENDIF ; ------------------------------------------------------- self.SetCriticalStage( self.CritStage_DisintegrateEnd ) ; Ashpile finished ENDEVENT Edited December 27, 2020 by ReDragon2013 Link to comment Share on other sites More sharing options...
maxarturo Posted December 27, 2020 Author Share Posted December 27, 2020 There are some vanilla friendly ghost npcs that they only use the 'Ab Spell' and nothing more from the script, to those npcs i'm mostly referring. If they won't use 'Effect Shaders' - 'Explosions'... etc, why add the Ghost Ab by script and not directly, especially since they are 'Unique' actors. Thanks for the reply. Link to comment Share on other sites More sharing options...
Evangela Posted December 28, 2020 Share Posted December 28, 2020 Can you give an example of one of those NPCs? For ones I've ran across that use both the ability and the script, Beth was being fancy with trying to simulate the ghosts "phasing" in and out of existence every time they are hit with a weapon. This is done by turning off the shader and turning it back on. The script function appears to override the ability in this manner. Also, the ashpiles needs to be applied when they die. Link to comment Share on other sites More sharing options...
maxarturo Posted December 28, 2020 Author Share Posted December 28, 2020 Hey Rasikko. First of all i would like to say thanks and a big SORRY to anyone that read this post !, please just pretend that this never happened... The last couple of days i ate too much sugar, and i'm not allow to eat sugar or more than 1 cup of coffee per day, sugar has a very bad effect on me... worse than lsd !. Everybody keep sending all those sweets and cakes for christmas, and i'm all alone, my girlfriend is out of town so there isn't anyone around to control me, plus i can't go out cause of the 'quarantine lockdown', so i fell into a meaningless stupid mind trip. I woke up today and i feel like i've been swimming against the current for days, i took a look at the things i did the last two days... and O My God !!@!! i deleted everything... No more sugar for me please... Happy new year to everyone !!. Link to comment Share on other sites More sharing options...
Recommended Posts