Jump to content

Give a perk right at the beginning


Duriel7

Recommended Posts

Hello everybody,

 

I am since the beginning of the afternoon on a problem about giving perk right after the start of the main quest.

I succeeded in doing my other things such as creating recipes with requirements, scripting new diseases like DoT for radiation disease, and other cool things.

 

Now I wanted to give the PC a natural regeneration for my Hardcore balancing mod, on the model of ImplantRegenEffect. I created the perk, the ability, the effect and the script. Adding the perk by console is fine and works like a charm.

 

I'm trying to add the perk via getStageDone VCG01 60 == 1 like this :

scn 0DurielRegenPerkAddScript

BEGIN GameMode
    if getStageDone VCG01 60 == 1
        player.addperk 0DurielRegenPerk
    endif
END

But it doesn't work at all, I've also tried begin ScriptEffectStart but it doesn't seem to work either.

I'm totally out of ideas, and I can't find the mod I know to add a perk right at the installation of it, as I don't remember its name. I would rather have steal the script idea to make mine but... yeah... can't find it.

 

I take whatever could work, I'm fed up with testing.

I also tested my work with and without Roleplayers Alternate Start, I want my own mod to be compatible with it.

 

Anyway thanks to all of you who could help and suggest ideas.

Link to comment
Share on other sites

Don't use numbers for the beginning of any variables or Editor-IDs (i.e. "0DurielRegenPerk"). Please see 'TIP: Best Practice - Do not begin Editor-IDs with numbers' in the 'Scripting' section of the wiki "Getting started creating mods using GECK" article.

 

As "GetStageDone" only returns 1 if true, and any function that returns only 0 or 1 can be used in a boolean test, try just "if (getStageDone VCG01 60)". When a function has multiple parameters, it's best to use parens to ensure it's parsed correctly.

 

You also need to "gate" that perk addition (e.g add a "DoOnce" variable check) so it is only applied once. (I realize you may know that and just presented a simplified bit of code, but it can't hurt to remind everyone.)

 

-Dubious-

Link to comment
Share on other sites

Hello,

 

Hey thanks for the answer, but the 0 is not part of a variable name, it's the name of my perk. Maybe it could be a problem so I changed the name of my perk and tested but nothing.

 

Yeah I did the DoOnce thing with a switch type short, inspired by the code from the Courier's Stash script. I don't know if it's efficient, but it didn't work with that. Although I think my code is correct, because if it is not, I can't quit the window, it surely have an error which I can't identify, parens or not, one method or another... it's a shame.

 

I just tried another method :

BEGIN GameMode
    if player.GetPermAV Survival >= 1
        if player.HasPerk 0DurielRegenPerk == 0
            player.addperk 0DurielRegenPerk
        endif
    endif
END

Which doesn't work either.

 

Then I tried

int SwitchPerk

BEGIN GameMode

    if player.HasPerk aaaDurielRegenPerk == 0
        set SwitchPerk to 0
    endif

    if player.GetPermAV Survival >= 1
        if SwitchPerk == 0
            player.addperk aaaDurielRegenPerk
            set SwitchPerk to 1
        endif
    endif
END

With and without parens. It's the same. Maybe it's because the PC surely gets the 1 survival and I must choose a higher number ?

So I tried Survival >=20 but nothing good came out of it.

 

EDIT : I inspired this above one from xatmos' mod Skill Based Perk, it is obvious but I must say it. As it didn't work, I'm wondering why. Hard to tell when lacking many hours of sleep.

 

Also I have another question, I'm trying to get my char have endurance * 20 only as starting HP, because changing the gamesetting fPCBaseHealth from 2 to 1 doesn't anything, but my change of lvl bonus from 5 to 2 changed effectively even on my already started test character.

Anyways here is the code to achieve the endurance * 20 thing :

int Endu
int StartingHP


BEGIN GameMode

set Endu to player.GetPermAV Endurance
set StartingHP to Endu * 20

But each time that I manually had the perk, it kills my char.

I tried with modav health -100 before but it's the same result. I thought that was because of the GameMode, so I have consoled modav health +1000 and add the perk, and saw the HP going down fast. I don't understand how can be this difference between console modav and scripted modav, and why is the setav doing the same thing ? It's a mess, I read many things on Beth's tutos, but I may have passed on some things, as I am utterly tired.

Speaking about being tired, I'm sorry for the potential orthographic/syntaxic/other mistakes, it's almost 3.00 AM here.

 

Again thanks to you Dubious, I'm sure your suggestions were usefull but even using them, it didn't solve my problem about the perk not being automatically given to the character.

 

EDIT 2 : Correcting the most obvious mistakes, hope this is good enough.

Edited by Duriel7
Link to comment
Share on other sites

Sounds like maybe to much is going on in the intro , are you sure the perk doesn't get added later after things settle down?

I would avoid using these gamemode blocks , especially right in the beginning of a game starting.

 

Try using an "OnActivate" on some sort of activator the player has to walk up and activate , or a "OnTriggerEnter" with a trigger box. Placed in front of the vigor tester for example.

Link to comment
Share on other sites

Mktavish,

Such a great idea. I thought about doing something like that, but with the stage for the quest Doc Mitchell gives the player. But as I said I want it to be compatible with Alternate Start mod, so I threw out this idea.

But your suggestion might work, I'm testing it right now.

 

Also yes I'm "sure" the perk doesn't get added few moments later because I stayed in the game sometime to be sure to see it.

 

EDIT : I just had another idea, as I want my perk to be given only on Hardcore mode activation, I maybe have to adapt a bit the corresponding script.

 

This would give the following :

ScriptName VCG01CasualHardcoreMessageSCRIPT

short nButton
short bModeSet;

BEGIN OnActivate
    ShowMessage VCG01CasualHardcoreMessage 1
END

BEGIN GameMode

    set nButton to GetButtonPressed
    if (nButton >= 0 && bModeSet == 0)
        if ( nButton == 1)
            SetHardcore 1;
          >>>  player.addperk aaaDurielRegenPerk; <<< my new line
        else
            SetHardcore 0;
        endif
        set bModeSet to 1;
        MarkForDelete;
    endif

END

I'm testing it right now.

 

EDIT 2 : It worked. For only one time, and the other characters I created to test didn't recieve the perk. That's lame. I thought every new game I would press the button yes for hardcore would work correctly.

 

EDIT 3 : Holy cow, I know, it's Alternate Start, it's modfying the same script and my mod was placed by GECK after all the others and I forgot to replace it at the good place. I put it at the end and it worked, that's why. Ok, so my mod should also break Alternate Start scripting for the Hardcore message. That's why I created another script based on the Hardcore one, with button activation required and such.

If it works well I'll put the exact code and explain for the others to use and understand.

Edited by Duriel7
Link to comment
Share on other sites

Ok, I permit myslef to double post because it's new, I've succeeded in doing what I wanted to do.

I thank you once more Mktavish for your suggestion which unblocked me.

Here's the real code :

ScriptName VCG01CasualHardcoreMessageSCRIPT

short nButton
short bModeSet;
int Endu
int StartingHP

BEGIN OnActivate
    ShowMessage VCG01CasualHardcoreMessage 1
END

BEGIN GameMode

    set nButton to GetButtonPressed
    if (nButton >= 0 && bModeSet == 0)
        if ( nButton == 1)
            SetHardcore 1;
            ShowMessage 0DurielNatRegenMessage 1
            player.addperk aaaDurielRegenPerk;
            set Endu to player.GetPermAV Endurance
            set StartingHP to Endu * 20
            player.setav health StartingHP
        else
            SetHardcore 0;
        endif
        set bModeSet to 1;
        Disable
        MarkForDelete;
    endif

END

I deleted Alternative Start modification as it was just the "Disable" thing, I added it in my script modification.

As you can see, it's the Hardcore message script because I wanted to make my own script and add references to the Hardcore one, but the GECK would not let me do that, I don't know why yet.

 

So I created a test message, which shows and you have to click on the "OK" button to pass it, and that let you see the new perk. Additionnally, I set the starting health of the PC to Endurance * 20, which is better to have the stress of being killed fast in Hardcore Mode.

 

This just let me the last problem : I want to deactivate the perk when the player switches to OFF the Hardcore Mode, and reactivate it when they switches back ON.

To achieve this, I've done :

    if (isHardcore == 0 && player.hasperk aaaDurielRegenPerk == 1)
        player.removeperk aaaDurielRegenPerk;
        ShowMessage 0DurielNatRegenMessage 1
    elseif (isHardcore == 1 && player.hasperk aaaDurielRegenPerk == 0)
        player.addperk aaaDurielRegenPerk;
        ShowMessage 0DurielNatRegenMessage 1
    endif

But I don't know if "isHardcore" is the correct function to do that. It doesn't work. I'm still searching and testing ATM but I would take help or ideas if you have.

Link to comment
Share on other sites

Per the GECKWiki "isHardCore" function example, it would appear to require a "player." ref prefix. When functions don't appear to be working correctly, get more explicit. Relying upon "implicit" references sometimes fails unexpectedly.

 

Avoid compound conditionals whenever possible. Better to construct a compound after you have confirmed the more simplified logic (one condition per test) is working correctly first. Then you can tell if your compound is constructed incorrectly or not. Suggest alternative similar to this:

; Player only gets this perk when in Hardcore mode
if (player.isHardCore == 0)
  if (player.hasperk aaaDurielRegenPerk == 1)
        player.removeperk aaaDurielRegenPerk;
        ShowMessage 0DurielNatRegenMessage 1
  ;else nothing to do
  endif
elseif (player.hasperk aaaDurielRegenPerk == 0)
        player.addperk aaaDurielRegenPerk;
        ShowMessage 0DurielNatRegenMessage 1
;else nothing to do
endif

-Dubious-

Link to comment
Share on other sites

I would get rid of that 0 on your message form ID ... could be causing problems , and any place else you are using numbers in the prefix of any form ID's. Things can go along fine for awhile , but then stuff just up and starts acting wonking not working in my experience.

 

When you said you wanted to reference the vanilla script ... did you mean you were trying to use ...

"GetScriptVariable" Like this ...

 

If GetScriptVariable VCG01CasualHardcoreMessageREF, nButton == 1

 

which that wasn't working for me either , and guess it can only be used in a condition field ?

So how you have to do it is ...

 

~~~~~~~~~~~~~~~~~~~~~~~~~

 

SCN MyHardcoreCheckScript

Int MyVar
Begin OnActivate
Set MyVar to VCG01CasualHardcoreMessageREF.nButton
If MyVar == 1
Player.AddPerk aaaDurielRegenPerk
endif
End
~~~~~~~~~~~~~~~~~~
And wondering what that other script fragment is on ? Quest , Object ... GameMode , OnActivate ?
The one Dubious rewrote for removing your perk if hardcore gets turned off/on later.
Cause I'm half thinking you may just want to put a IsHarcore condition on what makes the regen happen.
Then on the perk description , just say it only works in hardcore mode ... just a thought ?
Link to comment
Share on other sites

Per the GECKWiki "isHardCore" function example, it would appear to require a "player." ref prefix. When functions don't appear to be working correctly, get more explicit. Relying upon "implicit" references sometimes fails unexpectedly.

 

Oh... holy... I just totally forgot the player reference... like a fool and didn't see what was wrong... shame on me. Thanks for your eye on this.

Also thanks for your advice Dubious, I went from Java, we were told by teachers that && is cool to use for conditions, better than a series of simple if... naively I was thinking it's always good. Bu thinking of it, your way to do is pretty logical and convenient.

 

 

And wondering what that other script fragment is on ? Quest , Object ... GameMode , OnActivate ?
The one Dubious rewrote for removing your perk if hardcore gets turned off/on later.
Cause I'm half thinking you may just want to put a IsHarcore condition on what makes the regen happen.
Then on the perk description , just say it only works in hardcore mode ... just a thought ?

 

 

Thanks for the advices too. In fact, I use 0 because it's convenient to put My things on top of the rest, my other mod has just "Duriel" and I can find the lines by searching in the GECK, I will probably change them down the road to remove the zero. It exists many things in GECK with number, like the ammo for example, so I thought that was good to use numbers... But yeah. Doing the things the good way is always better.

 

Also I think I forgot the "REF" at the end of the VCG01blabla.nButton line, so that's why that wasn't working. Thanks for telling me.

 

To answer your question, it was in the HardCore Script so it was on the GameMode block. And yes your idea is good. But in my idea, now that you have told me that, I would do that like :

- player tell yes for hardcore and click the yes button;

- my script run and show the message with button click needed;

- then it kills itself via disable and markfordelete and let place to the begin gamemode block;

- with Dubious idea, which doesn't cause problems in the GECK, player can turn off and on the hardcore mode, and a floating message in the corner will show up to tell if the perk is given or removed, instead of a window message

 

I'm testing that right now, and will Edit the post to tell if it works, with the correct code again.

 

EDIT : So yeah, the code worked with the ref method. The method Dubious wrote worked but for one time, that's true. I don't know why, the Hardcore Mode is calculated in real time because we see the gauges disappear just after, that's something I could use maybe. If I find the portion of code corresponding.

EDIT 3 No, it was a false positive. I deleted the VCG01blabla script entry with FOMM, but for an unknown reason it was still there. The activator I placed would perfectly work on a normal game, but I can't place 16876716145 activators for Alternative Start. So I guess I'll stick with modifying the HardCore script for now.

EDIT 2 :

I tested this kind of script :

scn 0DurielRegenPerkSwitchScript

Begin GameMode

    if (VCG01CasualHardcoreMessageREF.bModeSet == 1)
        if (player.isHardCore == 0)
            if (player.hasperk aaaDurielRegenPerk == 1)
                player.removeperk aaaDurielRegenPerk
                ShowMessage 0DurielNatRegenMessage 1
            endif
        else
            if (player.hasperk aaaDurielRegenPerk == 0)
                player.addperk aaaDurielRegenPerk
                ShowMessage 0DurielNatRegenMessage 1
            endif
        endif
    endif

END

I thought with the condition of bModeSet always being to 1, the script for switching would be running each time the player switched on/off. But no.

 

Finally I need to thank both of you guys for helping me. I will probably try again the turn off/on thing for awhile but I will concentrate on finishing the recipe side of my Hardcore mod for now. As the result I obtained is good enough for me.

 

I don't know for now if I'll release the mod because it's a three modules mod that overhaul the gameplay, the recipes, a good amount of gamesettings and most if the misc/food/healing items weight, and their functions/characteristics in game, but I do release it, I will mention you two for helping me.

Edited by Duriel7
Link to comment
Share on other sites

 

 

Thanks for the advices too. In fact, I use 0 because it's convenient to put My things on top of the rest, my other mod has just "Duriel" and I can find the lines by searching in the GECK, I will probably change them down the road to remove the zero. It exists many things in GECK with number, like the ammo for example, so I thought that was good to use numbers... But yeah. Doing the things the good way is always better.

 

Yes many a modder comes up with the idea to filter there form-ID's to the top of the list with numbers ... and as you noticed the developers also did it to some degree. But it has and does yield problems , and imo enough times to warrant never doing it , as a means to not have to worry about ruling it out when problems do arise. But each to their own with that ^shrug^

 

Also I think I forgot the "REF" at the end of the VCG01blabla.nButton line, so that's why that wasn't working. Thanks for telling me.

 

Well yes it definitely didn't work without the Ref suffix , because it brought up the error of it not being a valid reference.

But for me it would fail silently , not being able to save/close the script. Even with Geck pwr up.

So when I switched to the method of setting my own variable to that variable , It then was able to save , and stop gate my hardcore activator script check from working when "nButton" did not equal 1

 

 

I thought with the condition of bModeSet always being to 1, the script for switching would be running each time the player switched on/off. But no.

 

"bModeSet" appears to just be a doOnce variable ... so that once one of the buttons is pressed , it will stop that code block , and also Mark the ActivatorRef for delete , therefore getting rid of that instance of the script and any variables set.

So the only thing saved outside the script , is the Hardcore game setting.

 

I thought by making another activator and script , you were trying to avoid doing any editing to the vanilla script , which is recommended for mod compatibility. And even if you remove the Mark for delete leaving the ActivatorRef ... I don't think it will run that script when the player is not inside of Doc Mitchels house. According to this wiki page https://cs.elderscrolls.com/index.php?title=GameMode

this line "

Notes
  • The above statement is true, provided the script runs. Not all scripts run every frame, e.g, Quest scripts (see FQuestDelayTime) and scripts on references not loaded.

Although I realize that is one of the old pages even before Fo3 Geck ...

 

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

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