[Work Around] AddPerk to NPC

Post » Thu Jun 21, 2012 6:43 am

Hello all,
I have been working on a pretty big mod for weeks now (well big for me) and I am desperately trying to make it as "Other" mod friendly as possible but I constantly find hurdles in the road courtesy of Bethesda.
One of the most heart breaking ones for me was the fact that AddPerk() does NOT work on any actor but the player in Papyrus... OWCH!
As part of my mod RemoteCast() a specific spell from an ActorBase to the target and I wanted it to have the same perks as the player WITHOUT modifying said perks I came up with the following work around.
It's not very efficient or pretty :-) but it's the best I could do.
If anyone can think of a better way please let me know or I just hope this helps anyone else trying to make Spell/Actor mods.
(P.S. I svck at formatting on this forum really sorry for how it looks)


ActorBase Property LFabWizardAlt1 Auto		 ; Wizard Caster with Mage Armor Rank 1.ActorBase Property LFabWizardAlt2 Auto		 ; Wizard Caster with Mage Armor Rank 2.ActorBase Property LFabWizardAlt3 Auto		 ; Wizard Caster with Mage Armor Rank 3.ActorBase Property LFabWizardDes1 Auto		 ; Wizard Caster with Augmented Flames Rank 1.ActorBase Property LFabWizardDes11 Auto		 ; Wizard Caster with Augmented Flames Rank 1 & Intense Flames.ActorBase Property LFabWizardDes2 Auto		 ; Wizard Caster with Augmented Flames Rank 2.ActorBase Property LFabWizardDes12 Auto		 ; Wizard Caster with Augmented Flames Rank 2 & Intense Flames.ActorBase Property LFabWizardDes3 Auto		 ; Wizard Caster with Augmented Frost Rank 1.ActorBase Property LFabWizardDes13 Auto		 ; Wizard Caster with Augmented Frost Rank 1 & Deep Freeze.ActorBase Property LFabWizardDes4 Auto		 ; Wizard Caster with Augmented Frost Rank 2.ActorBase Property LFabWizardDes14 Auto		 ; Wizard Caster with Augmented Frost Rank 2 & Deep Freeze.ActorBase Property LFabWizardDes5 Auto		 ; Wizard Caster with Augmented Shock Rank 1.ActorBase Property LFabWizardDes15 Auto		 ; Wizard Caster with Augmented Shock Rank 1 & Disintegrate.ActorBase Property LFabWizardDes6 Auto		 ; Wizard Caster with Augmented Shock Rank 2.ActorBase Property LFabWizardDes16 Auto		 ; Wizard Caster with Augmented Shock Rank 2 & Disintegrate.ActorBase Property LFabWizardIll1 Auto		 ; Wizard Caster with Hypnotic Gaze Perk.ActorBase Property LFabWizardIll14 Auto		 ; Wizard Caster with Hypnotic Gaze & Animage Perk.ActorBase Property LFabWizardIll15 Auto		 ; Wizard Caster with Hypnotic Gaze & Animage & Kindred Mage Perk.ActorBase Property LFabWizardIll2 Auto		 ; Wizard Caster with Aspect Of Terror Perk.ActorBase Property LFabWizardIll24 Auto		 ; Wizard Caster with Aspect Of Terror & Animage Perk.ActorBase Property LFabWizardIll25 Auto		 ; Wizard Caster with Aspect Of Terror & Animage & Kindred Mage Perk.ActorBase Property LFabWizardIll3 Auto		 ; Wizard Caster with Rage Perk.ActorBase Property LFabWizardIll34 Auto		 ; Wizard Caster with Rage & Animage Perk.ActorBase Property LFabWizardIll35 Auto		 ; Wizard Caster with Rage & Animage & Kindred Mage Perk.ActorBase Property LFabWizardIll4 Auto		 ; Wizard Caster with Animage Perk.ActorBase Property LFabWizardIll5 Auto		 ; Wizard Caster with Animage & Kindred Mage Perk.ActorBase Property LFabWizardRes1 Auto		 ; Wizard Caster with Regeneration Perk.ActorBase Property LFabWizardRes11 Auto		 ; Wizard Caster with Regeneration & Respite Perk.ActorBase Property LFabWizardRes2 Auto		 ; Wizard Caster with Respite Perk.ActorBase Property LFabWizard Auto		  ; References the default no perks Caster Wizard.Keyword Property MagicArmorSpell Auto		 ; Reference the keyword for Armor spells like oakskin etc.Keyword Property MagicParalysis Auto		 ; Reference the keyword for Paralyse type spells.Keyword Property MagicDamageFire Auto		 ; Reference the keyword for Fire damage spells.Keyword Property MagicDamageFrost Auto		 ; Reference the keyword for Frost damage spells.Keyword Property MagicDamageShock Auto		 ; Reference the keyword for Shock damage spells.Keyword Property MagicInfluenceCharm Auto		; Reference the keyword for spells effected by Hypnotic Gaze Perk.Keyword Property MagicInfluenceFear Auto		; Reference the keyword for spells effected by Aspect of Terror Perk.Keyword Property MagicInfluenceFrenzy Auto		; Reference the keyword for spells effected by Rage Perk.Keyword Property MagicRestoreHealth Auto		; Reference the keyword for spells effected by Regeneration Perk.Perk Property Stability Auto		   ; MagicParalysisPerk Property MysticBinding Auto		  ; To Do / Duplicate Keyword with MageLight etc.Perk Property SoulStealer Auto		   ; To Do / Duplicate Keyword with MageLight etc.Perk Property OblivionBinding Auto		  ; To Do / Duplicate Keyword with MageLight etc.Perk Property AugmentedFlames Auto		  ; MagicDamageFirePerk Property AugmentedFlames60 Auto		 ; MagicDamageFirePerk Property AugmentedFrost Auto		  ; MagicDamageFrostPerk Property AugmentedFrost60 Auto		  ; MagicDamageFrostPerk Property AugmentedShock Auto		  ; MagicDamageShockPerk Property AugmentedShock60 Auto		  ; MagicDamageShockPerk Property IntenseFlames Auto		  ; Copied to MagicDamageFirePerk Property DeepFreeze Auto		   ; Copied to MagicDamageFrostPerk Property Disintegrate Auto		   ; Copied to MagicDamageShockPerk Property Animage Auto			; Copied onto all Influence* / Works better on Animals.Perk Property HypnoticGaze Auto		   ; MagicInfluenceCharmPerk Property KindredMage Auto		   ; Copied onto all Influence* / Works better on Humanoids.Perk Property AspectOfTerror Auto		  ; MagicInfluenceFearPerk Property QuietCasting Auto		   ; Need to add to almost every Wizard!?!?Perk Property Rage Auto			 ; MagicInfluenceFrenzyPerk Property MasterOfTheMind Auto		  ; NO CONDITIONS! Now effects Undead & Daedra & Machines.Perk Property Regeneration Auto		   ; MagicRestoreHealthPerk Property Respite Auto			; Copied to MagicRestoreHealth / Also restores stamina on healing spells.Perk Property Necromage Auto		   ; NO CONDITIONS! Incresed effect on Undead.Spell Property LFspDetect Auto		   ; Reference detection spell.ACTORBASE FUNCTION FunctionWizardCaster(ActorBase akWizard, Spell akSpell)Debug.Trace("Starting FunctionWizardCaster")akSpell = akSpell As SpellIF akSpell.HasKeyword(MagicParalysis)	  ; If player casts Paralyze based spell  IF PlayerRef.HasPerk(Stability)	   ; Stability Perk = Duration.   akWizard = LFabWizardAlt1   RETURN(akWizard)  ENDIFENDIFIF akSpell.HasKeyword(MagicDamageFire)	  ; If player casts Fire based spell.  IF PlayerRef.HasPerk(AugmentedFlames60)	 ; Augmented Flames Rank 2 = Extra Fire Damage.   IF PlayerRef.HasPerk(IntenseFlames)	 ; Intense Flames = NPC run away if health low.	akWizard = LFabWizardDes12	RETURN(akWizard)   ENDIF   akWizard = LFabWizardDes2   RETURN(akWizard)  ELSEIF PlayerRef.HasPerk(AugmentedFlames)	; Augmented Flames Rank 1 = Extra Fire Damage.   IF PlayerRef.HasPerk(IntenseFlames)	 ; Intense Flames = NPC run away if health low.	akWizard = LFabWizardDes11	RETURN(akWizard)   ENDIF   akWizard = LFabWizardDes1   RETURN(akWizard)  ENDIFENDIFIF akSpell.HasKeyword(MagicDamageFrost)	  ; If player casts Frost based spell.  IF PlayerRef.HasPerk(AugmentedFrost60)	 ; Augmented Frost Rank 2 = Extra Frost Damage.   IF PlayerRef.HasPerk(DeepFreeze)	 ; Deep Freeze = NPC freezes if health low.	akWizard = LFabWizardDes14	RETURN(akWizard)   ENDIF   akWizard = LFabWizardDes4   RETURN(akWizard)  ELSEIF PlayerRef.HasPerk(AugmentedFrost)	; Augmented Frost Rank 1 = Extra Frost Damage.   IF PlayerRef.HasPerk(DeepFreeze)	 ; Deep Freeze = NPC freezes if health low.	akWizard = LFabWizardDes13	RETURN(akWizard)   ENDIF   akWizard = LFabWizardDes3   RETURN(akWizard)  ENDIFENDIFIF akSpell.HasKeyword(MagicDamageShock)	  ; If player casts Shock based spell.  IF PlayerRef.HasPerk(AugmentedShock60)	 ; Augmented Shock Rank 2 = Extra Shock Damage.   IF PlayerRef.HasPerk(Disintegrate)	 ; Disintegrate = Turns NPC's to ash if health low.	akWizard = LFabWizardDes16	RETURN(akWizard)   ENDIF   akWizard = LFabWizardDes6   RETURN(akWizard)  ELSEIF PlayerRef.HasPerk(AugmentedShock)	; Augmented Shock Rank 1 = Extra Shock Damage.   IF PlayerRef.HasPerk(Disintegrate)	 ; Disintegrate = Turns NPC's to ash if health low.	akWizard = LFabWizardDes15	RETURN(akWizard)   ENDIF   akWizard = LFabWizardDes5   RETURN(akWizard)  ENDIFENDIFIF akSpell.HasKeyword(MagicInfluenceCharm)	 ; If player casts Illusion Calm based spell  IF PlayerRef.HasPerk(HypnoticGaze)	  ; Hypnotic Gaze Perk = Higher level NPC effected.   IF PlayerRef.HasPerk(Animage)	  ; Animage Perk = Higher level Animals effected.	IF PlayerRef.HasPerk(KindredMage)	; Kindred Mage Perk = Higher level Humaniods effected.	 akWizard = LFabWizardIll15	 RETURN(akWizard)	ENDIF	akWizard = LFabWizardIll14	RETURN(akWizard)   ENDIF   akWizard = LFabWizardIll1   RETURN(akWizard)  ELSEIF PlayerRef.HasPerk(Animage)   IF PlayerRef.HasPerk(KindredMage)	akWizard = LFabWizardIll5	RETURN(akWizard)   ENDIF   akWizard = LFabWizardIll4   RETURN(akWizard)  ENDIFENDIFIF akSpell.HasKeyword(MagicInfluenceFear)	 ; If player casts Illusion Fear based spell  IF PlayerRef.HasPerk(AspectOfTerror)	 ; Aspect of Terror Perk = Higher level NPC effected.   IF PlayerRef.HasPerk(Animage)	IF PlayerRef.HasPerk(KindredMage)	 akWizard = LFabWizardIll25	 RETURN(akWizard)	ENDIF	akWizard = LFabWizardIll24	RETURN(akWizard)   ENDIF   akWizard = LFabWizardIll2   RETURN(akWizard)  ELSEIF PlayerRef.HasPerk(Animage)   IF PlayerRef.HasPerk(KindredMage)	akWizard = LFabWizardIll5	RETURN(akWizard)   ENDIF   akWizard = LFabWizardIll4   RETURN(akWizard)  ENDIFENDIFIF akSpell.HasKeyword(MagicInfluenceFrenzy)	 ; If player casts Illusion Frenzy based spell  IF PlayerRef.HasPerk(Rage)		; Rage = Higher level NPC effected.   IF PlayerRef.HasPerk(Animage)	IF PlayerRef.HasPerk(KindredMage)	 akWizard = LFabWizardIll35	 RETURN(akWizard)	ENDIF	akWizard = LFabWizardIll34	RETURN(akWizard)   ENDIF   akWizard = LFabWizardIll3   RETURN(akWizard)  ELSEIF PlayerRef.HasPerk(Animage)   IF PlayerRef.HasPerk(KindredMage)	akWizard = LFabWizardIll5	RETURN(akWizard)   ENDIF   akWizard = LFabWizardIll4   RETURN(akWizard)  ENDIFENDIFIF akSpell.HasKeyword(MagicRestoreHealth)	 ; If player casts Restoration Healing based spell  IF PlayerRef.HasPerk(Regeneration)	  ; Regeneration = Healing spell cure 50% more.   IF PlayerRef.HasPerk(Respite)	  ; Respite = Heals stamina also.	akWizard = LFabWizardRes11	RETURN(akWizard)   ENDIF   akWizard = LFabWizardRes1   RETURN(akWizard)  ELSEIF PlayerRef.HasPerk(Respite)   akWizard = LFabWizardRes2   RETURN(akWizard)  ENDIFENDIFDebug.Trace("No perks detected so Wizard is " + akWizard + " i.e. Base Wizard")IF akWizard == None  akWizard = LFabWizard  RETURN(akWizard)ENDIFENDFUNCTION
User avatar
Charlotte Lloyd-Jones
 
Posts: 3345
Joined: Fri Jun 30, 2006 4:53 pm

Post » Thu Jun 21, 2012 1:15 pm

Please note the above still isn't finished yet I still need to add some perks like Master of the Mind and Necromage but without creating triple the number of current ActorBase's I'm not sure how to do it.
This whole process is long winded but apart from creating an ActorBase for each possible player perk set up I don't know what else to do. Fortunately Keywords really reduce the numbers down, shame GetAssociatedSkill() doesn't work on spells or I would have this done in half the time!
User avatar
Darlene Delk
 
Posts: 3413
Joined: Mon Aug 27, 2007 3:48 am

Post » Thu Jun 21, 2012 4:35 am

Please note the above still isn't finished yet I still need to add some perks like Master of the Mind and Necromage but without creating triple the number of current ActorBase's I'm not sure how to do it.
This whole process is long winded but apart from creating an ActorBase for each possible player perk set up I don't know what else to do. Fortunately Keywords really reduce the numbers down, shame GetAssociatedSkill() doesn't work on spells or I would have this done in half the time!

In a nutshell, what are you doing here? I apologize for my laziness, but I am interested in this but didn't feel up to reading through the script as it is rather large. Also, have you considered using formlists to cut down on those properties?
User avatar
Ludivine Dupuy
 
Posts: 3418
Joined: Tue Mar 27, 2007 6:51 pm

Post » Thu Jun 21, 2012 7:52 am

It looks like the script is all for a function to choose an actor base for which to cast a spell. I think this stems from the post you made about RemoteCast not accounting for perks.

For example, if you are using RemoteCast to put the blame for a spell on the player, you want the spell to have damage as though it was cast from the player.

Function RemoteCast(ObjectReference akSource, Actor akBlameActor, ObjectReference akTarget = None)

So in order for the damage to be accurate, akSource should be an actor with similar stats and perks as the player. The function in the opening post seems to be for figuring out which ActorBase to use depending on what perks the player has, and then spawning the ActorBase in order to use the spawned actor for a RemoteCast.
User avatar
NEGRO
 
Posts: 3398
Joined: Sat Sep 01, 2007 12:14 am

Post » Thu Jun 21, 2012 2:29 am

I was part of the way in to making a companion mod that took advantage of something vaguely similar to what you're doing here when I started building Torment. I'm kicking myself now for not finishing it up.
User avatar
Oscar Vazquez
 
Posts: 3418
Joined: Sun Sep 30, 2007 12:08 pm

Post » Wed Jun 20, 2012 11:29 pm

@Elseagoat
Sorry should have explained it better at the top of the post. This is park of a quest script, I needed to reuse a lot of code between my spells so calling a function from one script source is so much easier. Only problem is different spells get passed to the akSpell so I needed an "other mod" friendly way of determining what perks are applicable to akSpell that the player has then create a caster Wizard ActorBase to cast it applying correct perk bonus's. Because AddPerk() does not work on NPC's at all in papyrus I have had to create dozens of ActorBases to make up for this.
(by other mod friendly I mean I want my mod to work even with those whom have altered the vanilla perks.)

RandomNoob is exactly right on his assumption.
Unfortunately I don't think a formalist will help me because I have to check any keywords from the spell to workout what perks will apply and I don't know how to link the WzardRef to the correct ActorBase alias with a form list to have the correct perks the player does.

I will add Master of the Mind to my script but I am going to have to leave out Necromage because there are not Keywords I can use from the spell to detect when to add the perk. If I wanted to add Necromage in this way I would have to literally double the number of ActorBase.
User avatar
Bad News Rogers
 
Posts: 3356
Joined: Fri Sep 08, 2006 8:37 am

Post » Thu Jun 21, 2012 1:10 am

You might be interested in this http://www.gamesas.com/topic/1359044-reanimate-target-actor/page__p__20495411__hl__reanimate__fromsearch__1#entry20495411. Specifically, the post at the bottom by mofomojo. He doesn't say if his method benefits from player perks though, but it should since in this case the player is actually casting it?

You could have a dummy scripted spell that you RemoteCast on something. The script then has the player Cast a self targeted spell on the target.
User avatar
Crystal Birch
 
Posts: 3416
Joined: Sat Mar 03, 2007 3:34 pm


Return to V - Skyrim