KingGsterUK Posted December 12, 2013 Share Posted December 12, 2013 (edited) This was supposed to be a legitimate question to anyone out there with scripting experience but nearing the end of writing this lengthy post, after fleshing out my scenario to all of you and proof-reading what I'd written, I finally figured it out. The mistake is laughable and certain parts may also trigger peoples humor, that and this might actually be of some use to people who may encounter the same problems as me - is why I'm submitting a question, with an answer all by the same guy without edits. That seems so weird but without further ado, the original post: Hi all. I'm working on a practice mod to learn the basics of quests, dialogue and scripting. I have a quest, that so far, gives the player 2 objectives to complete at the end of some dialogue with an NPC. The objectives are like prerequisites (Obviously) :blink: for the next stage. But they're a bit... Weird. Well, one is.#1 Reveal hidden contents Objective Index | Display Text | TargetRef | Conditions | ____________________________________________________________________________ 0 | Own 5000 Gold | ThePropositionAliasPlayer | No Condition | 1 | Gain a level | ThePropositionAliasPlayer | No Condition | I've never seen an objective in game that instructs you to "gain a level" and I'm struggling to find a way to complete "Objective Index 1" on a level-up event. I have an "NPC", a "quest", some "stages", some "objectives", some "dialogue", an "alias" pointing to the player and a "quest script". If I could write the script I needed in English, it would look something like this:#2 Reveal hidden contents When the Player levels up Check if we are on Stage 20 of QuestTheProposition Check if we haven't already completed Objective 1 of QuestTheProposition Complete Objective 1 of QuestTheProposition Even if I converted that into code it wouldn't work and would look something like this:#3 Reveal hidden contents Scriptname ThePropositionScript extends Quest {Controls The Proposition questline} Quest Property ThePropQuest Auto ;This points to ThePropositionQuest Int ThePropStage event OnStoryIncreaseLevel(int newLevel) ThePropStage = ThePropQuest.GetCurrentStageID() if ThePropStage == 10 ThePropQuest.SetObjectiveCompleted(1) endIf endEventI get no errors compiling the above code. It doesn't work because it's not getting the event sent by story manager. That's understandable because I haven't told story manager to start this quest on level up and "I don't want it to start an already running quest up". Understandable, understandable. :huh: So I created a new "Silent" quest, QuestThePropLevelEvent, selected the "Increase Level" Event and added a new Branch/Quest to Story Manager, pointed it to the new quest and set some conditions. I then made a new script to go with the "Silent quest", with just this in it:#4 Reveal hidden contents Scriptname ThePropLevelScript extends Quest {Confirms level up} Event OnStoryIncreaseLevel(Int newLevel) Debug.MessageBox("Level Up") endEvent Bingo. I get the Message Box popping up, confirming the level up and had a :dance: type of moment!I thought, great, all I need to do now is set the stage of the other quest from here. <--- The True Moment Of Eureka and the point where I answered my own question I was going to ask "HOW THE HELL DO I CHANGE THE PROPERTY IN MY MAIN QUEST's SCRIPT FROM INSIDE THE SILENT QUEST's SCRIPT!!?? all friendly like. The thing is I don't need to change the property of my "Main quests script", that property shouldn't even be there, because that quest isn't receiving the event from Story Manager. Deleting everything in the "Main quest's script" and putting it all in the "Silent quest's script" should do what I am trying to do. To actually finish off what needs to be done to get this to work is:1) Copy/delete the code from ThePropositionScript2) Paste it into ThePropLevelScript3) Point the property towards "QuestTheProposition"4) Save everything and try it out in game And Kaboom! Everything works! Happy G :woot: Note:Checking whether the player had 5000 gold in their inventory was quite simple to figure out from the creation kit reference pages. Whether I'm doing it the most efficient way, is not likely but it's working. For anyone that wants to implement an objective similar to "Objective Index 0" in the above table, can do so like this in the #6 spoiler tags and anyone else interested in code or wanting to optimize it can read it too:#6 Reveal hidden contents A rough guide to completing a quest objective when the player has a certain amount of gold, using scripts.1) Create a quest1.1) Create some quest stages1.2) Create a quest objective1.3) Create some dialogue in the quest for an NPC quest giver1.4) Copy and paste this into the script "Fragment" section of the dialogue window, when your NPC has said all he needs to say and says "goodbye":GetOwningQuest().SetStage(10) ;Adjust the value 10 to your particular quest stage or delete this line entirely GetOwningQuest().SetObjectiveDisplayed(0) ;Adjust the value 0 to your Objective Index Number1.5) Read the comments in the code and adjust the values accordingly 2) Create a new quest alias3) Give it a unique name4) Put a tick in these boxes: "Allow reuse in quest", "Allow disabled". (not certain whether it's actually necessary but mine has)5) Highlight "Unique actor" and from the drop-down box select "Player"6) Click on "Add" (script section to the right)7) Click on "[NEW SCRIPT]"8 ) Give the script a unique name9) Make sure it extends ReferenceAlias and click OK10) Right click your script from the "ReferenceAlias" window and select "Edit Source"11) In the "top box", "under all the text" that's currently in there, on a "new line" copy and paste this:Actor Property mySelf Auto12) Click file, save, then close.13) Click on your script again from the "ReferenceAlias" window, and click on properties.14) Click on the "mySelf" Property15) Click "Edit Value"16) From the "Cell" drop-down box, select "(any)"17) From the "Reference" drop-down box, select "PlayerRef ('Player')"18) Click OK19) Right Click your script again and click "Edit Source" again20) Copy and paste this into your script:Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, \ ObjectReference akSourceContainer) if GetOwningQuest().GetStage() == 10 ;Adjust the value 10 to your quest stage if !GetOwningQuest().IsObjectiveCompleted(0) ;Adjust the value 0 to your ojective index number if mySelf.GetGoldAmount() >= 5000 ;Adjust the >= operator and the value 5000 to match your quest objective display text GetOwningQuest().SetObjectiveCompleted(0) ;Adjust the value 0 to your ojective index number endIf endIf endIf endEvent21) Read the notes in the code( whatever comes after ; ) and adjust the values to suit your needs Now when we are in game and the quest which owns our new alias is running, when we add something to our inventory a script fires up and checks whether all the criteria in the if statements are true. If true, our quest objective will complete. But what if we already have 5000 gold when we first get the objective, I hear you say. Yes, indeed, the script won't fire because nothing's been added to our inventory. I haven't implemented it yet, and to tell you the truth, I've only just realized but I'm sure for cases like that, where we may have completed the criteria already, we could check at the same time as we issued the objective. I mainly include this guide for those that stumble upon it from forum searches and places like google. I hope it helps somebody. Note To Everybody Else Troubleshooting Code: Take some time to think about your code logically, even better from someone else's perspective. - Try and explain it, do a step-by-step, does it make sense? Can I make it more efficient? Do i even need to do it like this? - Things like that. Thank you to those who read this and Happy Modding :thumbsup: Edited December 12, 2013 by KingGsterUK Link to comment Share on other sites More sharing options...
Xander9009 Posted December 12, 2013 Share Posted December 12, 2013 (edited) To answer your original question, that is "HOW THE HELL DO I CHANGE THE PROPERTY IN MY MAIN QUEST's SCRIPT FROM INSIDE THE SILENT QUEST's SCRIPT!!??" You can actually do that fairly simply once you know how. Imagine quest one is titled Quest1. You could probably guess quest 2 would be titled Quest2. Follow the same scheme for the scripts and variables.ScriptName QuestScript1 Extends Quest Int Property Variable1 Auto Event OnInit() RegisterForUpdate(1.0) EndEvent Event OnUpdate() DoSomethingWithVariable1 EndEventScriptName QuestScript2 Extends Quest QuestScript1 Property Quest1 Auto Event SomeEvent() (Quest1 as QuestScript1).Variable1 = 3 EndEventThe first script will continually update and it'll be working with an empty variable. When the second script's event runs, it'll set the first script's variable to 3 so it'll now be using that value. Most important bits areWhen declaring the property for the quest (or some other type or property), the type gets replaced with the script, the property name can be anything (it's just a normal property).When calling the other script to get its functions or properties, you must put "(PropertyName as ScriptName).Property\Function". Putting it in parentheses and using as will combine them into a single unit so the following calls work correctly.I believe the "extends" section in the script you're calling is what defines the property type. By that I mean Script1 extends Quest. That means the Quest1 property in QuestScript2 will actually be a property of type "quest" just like if you'd typed "Quest Property Quest1 Auto". If you're getting mismatch errors, that might be the problem.It can be used on objects and actors as well. No matter the type, just make sure to fill the property like normal. Edited December 12, 2013 by Xander9009 Link to comment Share on other sites More sharing options...
SkyrimModHunter Posted December 17, 2013 Share Posted December 17, 2013 (edited) Hi, Thank you for your above post. Would you mind posting your final version of the "silent quest" that you did for objective 1? Additionally, did you release the mod? I'd love to be able to open it up in the creation kit and look at the quest, or if you could take a screenshot of your quest stages in the creation kit, that would be really nice. I've been working on a new race for about a year now. So far I've fumbled through papyrus enough to make several scripts that extend magic effects, but since I've never even made a quest, I don't know where to start. What I think I'm needing is to make a quest, with a script, that will add and remove "racial power" spells, as the player reaches various levels. Here's my attempt to rework your script for my needs. It compiles, but I still don't know how to setup it's quest stages or what is needed to make those stages correlate to various player levels. Reveal hidden contents Scriptname yyyDhaerrowLevelUpController extends Quest {will hopefully eventually be used to level up racial powers by removing the current tier of spell or power and then adding the next higher tier of a spell or power}Event OnStoryIncreaseLevel(int NewLevel) Debug.Trace("Something just reached level " + NewLevel) Int TheQuestStage Actor target = Game.GetPlayer() TheQuestStage = yyyLevelUpTracker.GetCurrentStageID() if TheQuestStage == 10 yyyLevelUpTracker.SetObjectiveCompleted(1) target.removespell(FaerieFire0) ; used to remove the first tier of the starting power Faerie Fire target.addspell(FaerieFire1) ; used to add the second power tier of Faerie Fire endIfEndEventQuest Property yyyLevelUpTracker Auto ; this points to "yyyLevelUpTracker" questSpell Property FaerieFire0 AutoSpell Property FaerieFire1 Auto On a side note, how to I make the script verify if the player is the person who is leveling up? Doesn't that need to be done so that the quest stages wouldn't advance when something like a follower levels up? Thank you in advance for any help that anyone might be williing to offer! Edited December 17, 2013 by SkyrimModHunter Link to comment Share on other sites More sharing options...
Xander9009 Posted December 17, 2013 Share Posted December 17, 2013 You'll have to wait for KingGsterUK for the rest, but I can answer the last question. No, you don't need to do anything special. NPCs don't level up. Even if their level changes, it's only changing, not "levelling up". AT least, that should be the case. Link to comment Share on other sites More sharing options...
SkyrimModHunter Posted December 18, 2013 Share Posted December 18, 2013 On 12/17/2013 at 11:54 PM, Xander9009 said: You'll have to wait for KingGsterUK for the rest, but I can answer the last question. No, you don't need to do anything special. NPCs don't level up. Even if their level changes, it's only changing, not "levelling up". AT least, that should be the case. That's good to know. Thank you. Link to comment Share on other sites More sharing options...
KingGsterUK Posted January 1, 2014 Author Share Posted January 1, 2014 @SkyrimModHunter - My apologies for not being around over Christmas time and not noticing your trouble sooner, I've recently had an Infinity Engine addiction, hence my absence. (Oh how I wish that modding scene was as active as this one :sad: ) I hope posting this information can still be of some use to you. ------------------------------------------------------------------------------------------------------------------------------ What you need:Main quest - Has stages, objectives, aliases and dialogueSilent quest - Doesn't have any of the above, it's just a shell with a script attached to itAdd your silent quest to story manager, so it will receive events from story manager First off, my main quest has a "blank script", nothing in it other than the script name. It doesn't need one at all but I'm not deleting it because I may still use it, for something. Secondly, this is the script that is attached to the "Silent Quest".Scriptname ThePropLevelScript extends Quest {Completes an objective in another quest on level up.} Quest Property ThePropQuest Auto ;This points to ThePropositionQuest (your main quest) Int ThePropStage ;declare an integer variable event OnStoryIncreaseLevel(int newLevel) ;Recieve event from StoryManager, integer variable unused ThePropStage = ThePropQuest.GetCurrentStageID() ;Our declared variable is now the current stage of the main quest at the time of this event if ThePropStage == 10 ;This is checking if we are on the correct stage ThePropQuest.SetObjectiveCompleted(1) ;If we are, do this if ThePropQuest.IsObjectiveCompleted(0) ;Check if we've also completed the other objectives while we are at it ThePropQuest.SetStage(20) ;If we have, advance the stage on to the next ThePropQuest.SetObjectiveDisplayed(10) ;Also advance the objective displayed endIf endIf endEventThirdly, if you'd still like to pull the mod apart yourself, I've included it here, attached to this post. It's not really a mod, and doesn't deserve to have a full release. It was just the beginning of an overly ambitious project that aimed to allow the player and an NPC to build a central marketplace in Solitude, from planning and hiring to building and managing. A place where the player could place bulk orders for crafting supplies, botanical supplies, cooking supplies as well as hire staff, manufacture and sell products. It was meant to be a business mod that would be unrivaled with real-time building, new animations for carrying and laboring and constructing, Horse and cart deliveries and much more. My imagination is getting carried away again, I think I'll leave it there. TheBusinessPartner.rar contains TheBusinessPartner.esp ONLY - I can guarantee it's saftey Happy modding :) Link to comment Share on other sites More sharing options...
Recommended Posts