Jump to content

Adding perks via potions/spells


Recommended Posts

You obtain the ActorAV and then you store it.

I'm using operator: Minor or Equal to 50 Alchemy



EVENT SomeEvent....
Float fPlayerAlchemy = PlayerREF.GetActorValue("Alchemy")
If ( !PlayerRef.HasPerk(MedAlchemyAlchemyRedone) ) && ( fPlayerAlchemy <= 50 )
;;;;; Do My Stuff
EndIf
ENDEVENT

Edited by maxarturo
Link to comment
Share on other sites

This will add the 00AlchemyRedone on first reading.

If player reads it again when their skill is 30+, they will gain the 30 perk, and so on. If book is read when skill is not high enough for next perk, they will see the 'not ready' message. If book is read after 90 perk is gained, they get the 'learned all you can' message.

Scriptname AlchemyRedoneAddPerkExp extends ObjectReference

Actor property PlayerRef auto 
Perk property Alchemist00AlchemyRedone auto
Perk property Experimenter30AlchemyRedone auto
Perk property Experimenter50AlchemyRedone auto
Perk property Experimenter70AlchemyRedone auto
Perk property Experimenter90AlchemyRedone auto

Event OnRead()
    AddNextAlchemyPerk()
EndEvent

Function AddNextAlchemyPerk()
    float AlchemySkill = PlayerRef.GetAV("Alchemy")
    if !PlayerRef.HasPerk(Alchemist00AlchemyRedone)
        PlayerRef.AddPerk(Alchemist00AlchemyRedone)
    elseif !PlayerRef.HasPerk(Experimenter30AlchemyRedone) && AlchemySkill >= 30.0
        PlayerRef.AddPerk(Experimenter30AlchemyRedone)
    elseif !PlayerRef.HasPerk(Experimenter50AlchemyRedone) && AlchemySkill >= 50.0
        PlayerRef.AddPerk(Experimenter50AlchemyRedone)
    elseif !PlayerRef.HasPerk(Experimenter70AlchemyRedone) && AlchemySkill >= 70.0
        PlayerRef.AddPerk(Experimenter70AlchemyRedone)
    elseif !PlayerRef.HasPerk(Experimenter90AlchemyRedone) && AlchemySkill >= 90.0
        PlayerRef.AddPerk(Experimenter90AlchemyRedone)
    elseif PlayerRef.HasPerk(Experimenter90AlchemyRedone)
        Debug.Notification("You have learned all you can.")
    else         
        Debug.Notification("You are not ready yet to gain further insight from this book.")
    endif
EndFunction

 

And just in case, here is a link to a list of Actor Values one can get (and set) https://en.uesp.net/wiki/Skyrim_Mod:Actor_Value_Indices

Link to comment
Share on other sites

There is no need for a 'Function' (go sub) here, it's an overkill and has no actual use.

'Functions' are use for when a script needs to access the same lines of script more that once, or if another script will access the script handling the 'Function'.


Example:



Event OnActivate()
;;;;;; Some Stuff

AccessFunction() ;;;;;;GO SUB
ENDEVENT

EVENT OnCellDetach()
;;;;;; Some Stuff

AccessFunction() ;;;;;;GO SUB
ENDEVENT

FUNCTION AccessFunction() ;;;;;;SUB
;;;; Do The Same Cool Stuff
ENDFUNCTION

Edited by maxarturo
Link to comment
Share on other sites

Okay, I've got a question about another script - same mod, different function. I'm using portable alchemy stations; the original mod has them as armor that is equipped, but I want to make them misc items. I cut down the original script (hence the Game.GetPlayer), but will it work as is?

 

 

Scriptname AlchemyRedonePortable extends ObjectReference
 
ObjectReference Property ToolReference Auto
ObjectReference Property CraftingStationReference Auto
 
Event OnEquipped(Actor akActor)
 
If( akActor == Game.GetPlayer() )
CraftingStationReference.Activate( Game.GetPlayer() )
EndIf
 
EndEvent
Link to comment
Share on other sites

It's for me, not NPCs. I'm not sure what you mean here... are you saying I only need this?

 

 

Scriptname AlchemyRedonePortable extends ObjectReference
 
ObjectReference Property ToolReference Auto
ObjectReference Property CraftingStationReference Auto
 
Event OnEquipped(Actor akActor)
 
CraftingStationReference.Activate( akActor() )
 
EndEvent

 

 

I have another question while I'm here. The AlchemyRedoneAddPerkPotions script doesn't seem to be working. I successfully made a potion, but when I drank it, nothing happened. I also want to add a message ("Your knowledge of alchemy has advanced.") so that the player knows the perk has been added. The wiki is less than helpful on this point - all I can find out is that I have to use

 

Function Notification("Your knowledge of alchemy has advanced.") native global

 

but it doesn't say anything beyond that. You'd think they'd add something like sample scripts, right? Naaah. Why would they do that?

Link to comment
Share on other sites

'akActor' is not a function, you do not put parenthesis after it.

 

Also, what 'potions' are you talking about? Weren't you going to do it using a book? If you want it to work via a potion, you should define a 'script' type MagicEffect, and attach a script to it which has the add perk logic in the 'OnEffectStart' event. Then you define a Potion and assign this MagicEffect to it.

 

Functions do not exist just by themselves. Each function is a method of specific class. If a function is defined as 'global', it is called on the class itself. Otherwise, it needs to be called on an object instance of a class. Calling a function just by itself is a short way of calling it on 'Self' object (or class if it is global). A 'native' function is one that is implemented in game engine itself, so in Papyrus, there is only a declaration, no body.

 

Thus, you don't just call 'Notification' . It is a global, so you call it as method of the class it belongs to. Namely, Debug.

 

Debug.Notification("blah blah") <<< displays a message in upper left corner.

Debug.MessageBox("blah blah") <<< displays a popup message in middle of the screen and you need to click ok.

Debug.Trace("blah blah") <<< writes a line to game's Papyrus log.

 

If you want samples, there should be a TON of scripts in your Data/Source/Scripts, including all the scripts for various standard game classes, such as Actor.psc, Potion.psc, etc.

So if you want to see examples of how a particular function might be used, you can use something like GrepWin in that folder to search.

Link to comment
Share on other sites

Syntax can help. Spread a checking routine out a bit. You can always condense it later

 

Bool FirstCheckWasYes = AAA == BBB && WhateverCellCheckWeMightHave == True

 

Bool SecondCheckWasYes = FirstCheckWasYes == True && (WhateverAlchemyRecipe).GetPlayerKnows() == True

 

Bool OtherRouteThen = SecondCheck == False && Game.GetPlayer().GetItemCount(SomethingSomething) > 4

 

Bool OnlyTheFirstOneHasATaskForUs = OtherRouteThen == False && FirstCheckWasYes == True && SecondCheckWasYes == False

 

If SecondCheckWasYes

GogoABC()

ElseIf OnlyTheFirstOneHasATaskForUs

SomethingIDK()

ElseIf OtherRouteThen

KillNazeem()

EndIf

Link to comment
Share on other sites

'akActor' is not a function, you do not put parenthesis after it.

Oh. Right. You have to remember I'm a novice.

 

Also, what 'potions' are you talking about? Weren't you going to do it using a book? If you want it to work via a potion, you should define a 'script' type MagicEffect, and attach a script to it which has the add perk logic in the 'OnEffectStart' event. Then you define a Potion and assign this MagicEffect to it.

 

Sorry for being vague. There are two classes of perks I'm adding - one is added via book, and the other via potions. I made the magic effect and added the script to it - I know that much from Oblivion - then added the effect to the potion. I checked the effect against another mod I have that has potions with a script effect (changes starting spells), and they're more or less the same.

 

This is probably a dumb question, but does PlayerRef need to be defined in every script instance? Like, if I attach the same script to five objects, I have to define it in all five?

 

Functions do not exist just by themselves. Each function is a method of specific class. If a function is defined as 'global', it is called on the class itself. Otherwise, it needs to be called on an object instance of a class. Calling a function just by itself is a short way of calling it on 'Self' object (or class if it is global). A 'native' function is one that is implemented in game engine itself, so in Papyrus, there is only a declaration, no body.

 

Thus, you don't just call 'Notification' . It is a global, so you call it as method of the class it belongs to. Namely, Debug.

 

Debug.Notification("blah blah") <<< displays a message in upper left corner.

Debug.MessageBox("blah blah") <<< displays a popup message in middle of the screen and you need to click ok.

Debug.Trace("blah blah") <<< writes a line to game's Papyrus log.

Okay. I was looking through other scripts and saw the Debug.Notification thing, but I assumed it needed to be called like a normal function.

 

 

Another dumb question: when you compile a script, how do you get it to display errors? I did it once by accident, but I don't remember how I did it.

Edited by WalkerInShadows
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...