Fancy door + quest scripting. - Printable Version +- Frictional Games Forum (read-only) (https://www.frictionalgames.com/forum) +-- Forum: Amnesia: The Dark Descent (https://www.frictionalgames.com/forum/forum-6.html) +--- Forum: Custom Stories, TCs & Mods (https://www.frictionalgames.com/forum/forum-35.html) +--- Thread: Fancy door + quest scripting. (/thread-6941.html) |
Fancy door + quest scripting. - Streetboat - 03-18-2011 Hi all, I'm trying to make a little puzzle involving lighting a fireplace, a door, and a key. What I want to happen is the player needs to get through a door, but needs a key to do so. This I have all figured out in the script, works like a charm. There's an interim step in there, too. The player starts the level out freezing his buns off, and needs to get warm. I made this work as well, creating a quest as soon as the level starts and having it complete when a fireplace is lit. Now, the problem is, I want to tie the fireplace quest to being able to progress. I want to make it so the player can acquire the key, but not be able to use it on the door until he activates the fireplace. It should flash a message when he tries to use the key prematurely, saying "My hands are too frozen to do that." I feel like this is a fairly complex if...then script, and I have no idea where to even start. On the plus side, I do have working scripts for the key working and the fireplace completing the quest, separately. Take a gander: Code: void OnStart() This is paraphrased, btw. There are other scripts in there, but I only copy-pasted the ones that are pertinent to this question. Thank you for your time! RE: Fancy door + quest scripting. - Nye - 03-18-2011 You'll need to make use of the local variant function. Code: SetLocalVarInt("CUSTOM NAME HERE", INTEGER HERE); Set an if statement, so that Code: if(GetLocalVarInt("CUSTOM NAME") == CUSTOM INTEGER) So, when the player lights the fireplace, add the line Code: SetLocalVarInt("CUSTOM NAME HERE", INTEGER HERE); Then, the player wont be able to do anything until the integer of the variant matches the required value to run "STUFF HERE". You can be really fancy too, and add a Code: if(GetLocalVarInt("CUSTOM NAME") != CUSTOM INTEGER) The != meaning, 'NOT Equal to'. RE: Fancy door + quest scripting. - Streetboat - 03-18-2011 All right, thank you, that's definitely a start. I want to do more than just copy and paste that, though, I want to understand what to do. So, I set a variant in order to tell the game that the game can't unlock the door unless I have the key AND the fire is lit? What do I put for that integer? Also, where can I tell it to say "Your fingers are too frozen for that" when I try to use the key without the fire? Without that text, the player won't have any clue why he can't use it. Thank you very much for your help! RE: Fancy door + quest scripting. - Nye - 03-18-2011 (03-18-2011, 09:45 PM)Streetboat Wrote: All right, thank you, that's definitely a start. I want to do more than just copy and paste that, though, I want to understand what to do. Eugh, I was in a hurry to go to dinner when I posted that reply, so I didn't give it enough detail Okay, here goes: The integer which you set for the local variant, can take any value. For example, 0, 1, 2 , 3, 5, 10, 100. When you set the local variant, to for example, 1, when the game calls that variable, it will see that it holds the value, "1". We can manipulate this system. So, when the player interacts with the door, WITHOUT lighting the fire, the first thing you want to put inside the function is: Code: if(GetLocalVarInt("FireLit") != 1) By default, the game will run the procedure and unless you have already specified the value of your local variant, it will default to 0. In this case, it will run all the functions you have put inside the curly braces, as 0 is not 1, so it will show the message (until "FireLit" takes the value 1) In the above case, the player will see the message stored in your extra_english.hps file, under the category and entry name you have chosen and display for the custom time you choose. Now, second. We want to add a second 'IF' statement within our function that is called when we interact with the door. Code: if(GetLocalVarInt("FireLit") == 1) Now, only when the FireLit local variant takes the value 1, will the game run the stuff located in-between the curly braces. However, in order for the game to recognise when the player has lit the fire, upon running the function called when the player LIGHTS the fire, you need to add the line Code: SetLocalVarInt("FireLit", 1); And as an example for the if statements above, "If the local variant "FireLit" does NOT equal 1, then...INSERT STUFF in-between the curly bracket/braces." (!= means NOT equal is not assigned to...) and (== means equal/IS assigned to...). I hope this helped a little better, local variants are MASSIVELY useful for lots of things, especially when making larger, more complex custom stories If you get stuck, copy and paste your script and I will show you what you need to do RE: Fancy door + quest scripting. - Streetboat - 03-18-2011 All right, so here's the order of things I want: Interact with door: If key != in inventory, display message "I need a key." If key == in inventory, keep key and display message "My hands are too cold, I need to warm them up." Light fire: If key != in inventory, nothing happens. If key == in inventory, it will now work on door. I need to do some inventory things to make this work, it seems. Here's my code, anyways Code: void UsedKeyOnDoor(string &in asItem, string &in asEntity) It looks good to me, but it's missing parts, such as checking the inventory for the key when the door is used. This is really complicated considering I just started working with this code two days ago, but if it works this is gonna be great. Okay, so the code I just pasted above works almost perfectly. The only problem is that once the fire is lit, the key doesn't work on the door. It says "Can't use item this way!". However, the key does give the message that your hands are too cold if you use it without the fire. HOWEVER, if you light the fire before you pick the key up, the key works. RE: Fancy door + quest scripting. - Nye - 03-19-2011 I would rethink your logic slightly. There is no such thing as an 'inventory search'. You need to add a collide callback for when the player picks up the key. Here is the structure I suggest you use: Code: 0 Player INTERACTS with door // note: NOT using the key on door Your next question will probably be about callbacks, but it is late now, so ask any questions and I will check this thread again tomorrow morning RE: Fancy door + quest scripting. - Pandemoneus - 03-19-2011 Btw, Code: if(GetLocalVarInt("FireLit") == 1) { would do the same. RE: Fancy door + quest scripting. - Streetboat - 03-19-2011 Yeah, I'm confused. My problem is, It appears that after the script runs once, it won't run again. If I try the key with frozen hands, it gives the message and all is well. If I then go on to light the fire and try again, it says "Cannot use item this way!" If I light the fire first and then use the key, it works like a charm. It seems that once I run the script once either way, it won't work again. I don't understand. Also, I simply cannot get it to display the text when I use the door normally while it is locked. code: Code: void locked1(string &in EntityName, string &in Type) And I have 'locked1' as the PlayerInteractCallBack on the door itself. That same system worked just fine for my lantern script. :/ RE: Fancy door + quest scripting. - Streetboat - 03-19-2011 Additional problem: Could anyone possibly tell me what's wrong with this script? It's a different level from the other one. There are 00_woodshop and 01_house in terms of levels. When the player enters an area in 01_house, it's supposed to do what's in this script, but it just crashes instead. Is it not possible to check and see if a VarInt from another level is true? My first attempt was an 'if... else' using "HasItem" and checking for the lantern, but that also crashed. What am I doing wrong? Code: void OnStart() RE: Fancy door + quest scripting. - Nye - 03-19-2011 As for your first problem, regarding the callback being removed upon being run, when you declare the callback, for example: Code: AddEntityCollideCallback("Player", "needlantern", "lantern_warn", true, 1); The boolean expression, 'true' in the above case is the answer to "Delete on collide?". Changing this to false will stop it deleting on collide. So, in your case, to allow the player to use the key more than once. I always find the 'Script Functions' page on the Wiki is handy http://wiki.frictionalgames.com/hpl2/amnesia/script_functions So, if we use an entity collide callback, the syntax is Code: AddEntityCollideCallback(string& asParentName, string& asChildName, string& asFunction, bool abDeleteOnCollide, int alStates); If we wanted to allow two entities to collide and run the associated procedure more than once, we would change the boolean value 'bool abDeleteOnCollide' to false. Regarding the key on the door, the syntax and your syntax for the using key on door callback is: Code: AddUseItemCallback(string& asName, string& asItem, string& asEntity, string& asFunction, bool abAutoDestroy); Notice the 'boola abAutoDestroy'. We want this to be false, so that it doesn't remove the key each time. It's a little more complicated with items, since, you will then need to add another local variant check, when you run the procedure. For example: Code: void OnStart() Also, you can use an 'else' statement, to make it a bit quicker, as Pandemoneus says, but I find it is easier to understand what you were doing, using just if statements where possible. -------------------------------------------------------------------- With your second script, try ensuring that you have Code: void OnLeave() Code: void OnEnter() |