Hello, I'm new to the forums, I apologize if this is the wrong section to post my question in. ^_^"
I'm relatively new to the, I guess scripting community, and am having some trouble with a little test map I'm doing. I'm trying to make an omnitool open a locked door. I haven't been able to figure out the problem, but I keep getting the same error in the script which says:
"FATAL ERROR: Could not load script file 'maps/test_01.hps'!
test_01.hps (190, 5): ERR: No smatching signatures to
'CathTool_UseOnPanel(tString, tString)'
I had followed the developer test on the Steam workshop to try and get a feel for what I need to do, except I used my own names for everything. Well, I always got that script error above. Eventually I got frustrated, and had changed everything in the test map to the exact same things in the developer test, and even following the script word for word, and I still get the same script error above. When I was looking in the developer test script looking for anything based on the CathTool script, I only found one line of script for the CathTool which was the following:
if I do this: //CathTool_UseOnPanel("omnitool","omnipanel_finaldoor"); then I can open the map, but none of the GUI will load on the omnitool or the omnipanel. Instead, I get a ton of errors in the lower left hand corner as you can see in the pictures I will include. I don't know how to fix these errors, and its really frustrating. I'm probably overlooking something simple, or maybe it really is just difficult...
The code I used to open the door is the following:
/////////////////////////////////////////
// Event *Player uses omnitool to open final door*
//{//////////////////////////////////////
As I said... This is the exact copy from the developer test because I was frustrated and thought that this code would work, unfortunately, it didn't work for me.
Now onto the map itself...
The omnitool is named "omnitool", and under the "Entity" tab and under the "Tool" tab, I have it set to "omnitool_OnPickUp" under PickupCallback, "omnitool_OnUse", under UseCallback, "omnitool_CanBeUsed" under CanBeUsedCallback.
The omnipanel name is "omnipanel_finaldoor", and under the "Entity" tab under the "Connections" tab, the ConnectedEntity is "finaldoor".
There is a script area, or rather a tool area named "ToolArea_1", and under the "Area" tab under the "Tool" tab, the ToolsToEquip is the "omnitool".
The door is named "finaldoor".
The pictures included show that there is no GUI on the the omnitool or the omnipanel along with a bunch of errors that I have no idea how to fix.
Can anyone please help me fix this issue and explain what I've been doing wrong?
I've been getting this error as well. It's not a game-flow-breaking bug, though, so I haven't put a whole lot of effort in investigating what is causing it. My suspicion is that, since the omnitool has a part of it that is essentially a terminal, it assumes that any map that implements it is going to be making GUI calls to that terminal, and by default it searches for functions with specific signatures (like void CathTool_OnGui(const tString &in, float), for example). My guess is if you implement those functions in any way (even as empty functions), the errors should go away.
Though like I said, the errors don't really appear to hinder game performance in any way, so you could probably safely ignore them.
EDIT: Reading through some script files, I think that the signature could be _CathTool_OnGui(const tString &in, float) instead (note the leading underscore character). I'm not 100% sure, as I'm having some difficulty finding this function in SOMA level code.
(This post was last modified: 10-30-2015, 06:32 AM by Abion47.)
(10-30-2015, 05:53 AM)Abion47 Wrote: I've been getting this error as well. It's not a game-flow-breaking bug, though, so I haven't put a whole lot of effort in investigating what is causing it. My suspicion is that, since the omnitool has a part of it that is essentially a terminal, it assumes that any map that implements it is going to be making GUI calls to that terminal, and by default it searches for functions with specific signatures (like void CathTool_OnGui(const tString &in, float), for example). My guess is if you implement those functions in any way (even as empty functions), the errors should go away.
Though like I said, the errors don't really appear to hinder game performance in any way, so you could probably safely ignore them.
EDIT: Reading through some script files, I think that the signature could be _CathTool_OnGui(const tString &in, float) instead (note the leading underscore character). I'm not 100% sure, as I'm having some difficulty finding this function in SOMA level code.
How would I go about adding this to the code? I've tried just copying the "_CathTool_OnGui(const tString &in, float)" and "CathTool_OnGui(const tString &in, float)" into the code and I still receive errors. I no longer receive the "CathTool_UseOnPanel" error, but I now receive errors that say:
So right now in my code, I just have this pasted above everything
and I get the error that says:
FATAL ERROR: Could not load script file 'maps/test_01.hps'!
test_01.hps (164, 3): ERR: Expected method or property
test_01.hps (230, 1): ERR: Unexpected token '}'
If I get rid of the 'void; I get the same error. If I get rid of the first underscore I still get the same error. If I move the code down underneath everything, so its like this:
When you declare a function, it has to go where functions can be declared. This is either within a class body or on its own. It cannot be placed within another function's body.
To clarify what I mean, you can do one of two things. To declare a function as part of a class, you do this:
Notice how in both of these cases, the function declaration is accompanied by the curly brackets, which is the function body. When declaring a function, you have to also declare a body for that function, even if that body is completely empty.
(There are exceptions to these rules, but they deal with specific concepts in programming that you shouldn't ever need to worry about when making a mod.)
Also, the code void _CathTool_OnGui(const tString &in, float) is what is called a function signature, meaning that it contains the name, parameter types, and return value of a function. By itself, it is not valid syntax for declaring a function. To do that, you have to give the parameters valid names, as well as the function body that I mentioned earlier.
To talk about the specific errors you are mentioning, they are called syntax errors, which unlike the _CathTool_OnGui errors will not let your script be compiled until they are fixed.
ERR: Expected method or property means that there is a spot in your code where the compiler is expecting something but is not getting it. This happened when you pasted void _CathTool_OnGui(const tString &in, float), but didn't declare a method body using curly brackets.
ERR: Unexpected token '}' means that the compiler found something it wasn't expecting, which in this case was a closing curly bracket. This usually is a red herring error as it can be caused by other errors that are the actual roots of the problem. Fixing the other problems will generally resolve these as well.
ERR: Expected expression value is similar to the above error in that the compiler is expecting something it isn't getting. In this case, you moved void _CathTool_OnGui(const tString &in, float) into the body of another function, which isn't something that can be processed within a function body.
At any rate, I have to apologize. I misunderstood your original post. For some reason I thought the OnGui function was your core issue, when in fact your issue was the CathTool_UseOnPanel function.
The error ERR: No smatching signatures to 'CathTool_UseOnPanel(tString, tString)' means that in your code you are trying to call a function that according to the compiler doesn't exist. In this case, I imagine that when you were copying code from the test map, you didn't copy over the code at the top of the file.
All of the CathTool helper functions exist in a script file called "helper_custom_depth.hps". In order to use them in your code, you have to add #include "helper_custom_depth.hps" to the top of your script file. If you don't, then those functions will effectively not exist, and any calls to them will result in the above error.
(Incidentally, adding that line of code will also resolve the _CathTool_OnGui minor errors as well. That's good to know, though I kick myself for not thinking of that sooner.)
(10-31-2015, 12:04 AM)Abion47 Wrote: When you declare a function, it has to go where functions can be declared. This is either within a class body or on its own. It cannot be placed within another function's body.
To clarify what I mean, you can do one of two things. To declare a function as part of a class, you do this:
Notice how in both of these cases, the function declaration is accompanied by the curly brackets, which is the function body. When declaring a function, you have to also declare a body for that function, even if that body is completely empty.
(There are exceptions to these rules, but they deal with specific concepts in programming that you shouldn't ever need to worry about when making a mod.)
Also, the code void _CathTool_OnGui(const tString &in, float) is what is called a function signature, meaning that it contains the name, parameter types, and return value of a function. By itself, it is not valid syntax for declaring a function. To do that, you have to give the parameters valid names, as well as the function body that I mentioned earlier.
To talk about the specific errors you are mentioning, they are called syntax errors, which unlike the _CathTool_OnGui errors will not let your script be compiled until they are fixed.
ERR: Expected method or property means that there is a spot in your code where the compiler is expecting something but is not getting it. This happened when you pasted void _CathTool_OnGui(const tString &in, float), but didn't declare a method body using curly brackets.
ERR: Unexpected token '}' means that the compiler found something it wasn't expecting, which in this case was a closing curly bracket. This usually is a red herring error as it can be caused by other errors that are the actual roots of the problem. Fixing the other problems will generally resolve these as well.
ERR: Expected expression value is similar to the above error in that the compiler is expecting something it isn't getting. In this case, you moved void _CathTool_OnGui(const tString &in, float) into the body of another function, which isn't something that can be processed within a function body.
At any rate, I have to apologize. I misunderstood your original post. For some reason I thought the OnGui function was your core issue, when in fact your issue was the CathTool_UseOnPanel function.
The error ERR: No smatching signatures to 'CathTool_UseOnPanel(tString, tString)' means that in your code you are trying to call a function that according to the compiler doesn't exist. In this case, I imagine that when you were copying code from the test map, you didn't copy over the code at the top of the file.
All of the CathTool helper functions exist in a script file called "helper_custom_depth.hps". In order to use them in your code, you have to add #include "helper_custom_depth.hps" to the top of your script file. If you don't, then those functions will effectively not exist, and any calls to them will result in the above error.
(Incidentally, adding that line of code will also resolve the _CathTool_OnGui minor errors as well. That's good to know, though I kick myself for not thinking of that sooner.)
Oh my gosh, I'm so happy right now. I've been struggling with this code for days, and it turns out I was just missing one line of coding. The #include helper_custom_depth.hps was what I was missing. Very informative information you included above, too. You've helped me a lot. Thank you so much!
EDIT: How do I go about closing the door behind the player once they walk through, and they have to use the omnitool again to open the door? I figured that using a trigger area would work to close the door behind them, but I'm not sure of the code. I'm not used to SOMA's code, TDD was so much easier to code, but SOMA is so much more... Complex.
A code I tried to close the door behind the player, I had just typed:
bool CloseFinalDoor(const tString in asParent, const tString in asChild, int alState)
but I know that is wrong, and I got errors for it, too. I knew it wouldn't work, but I had just wanted to try it.
The trigger area, under the "Area" tab, under the "Collide Callbacks" tab the CC_Entities is "player" and the CC_Funcs is "CloseFinalDoor". The name of the trigger area is "CloseFinalDoor" though that probably doesn't chance anything.
=========================
I guess one of my main issues overall with coding is that I try to compare it to TDD, in which that code I understand for the most part. But something about coding SOMA, I just don't quite understand, like trigger areas for a small example: I know that there are no more "AddEntityCollideCallbacks" like Amnesia for script areas, so how do I make script areas in SOMA. It's by using the "Trigger" areas, correct? I know there is a tab where I can type under the CC_Funcs which are, I'm ASSUMING the same as "AddEntityCollideCallbacks", except coded differently - which is what I don't understand. I'm very... Confused. I have a great story in mind, one I've been working on since SOMA came out. I just don't know how to go about coding anything yet. @_@
(This post was last modified: 10-31-2015, 04:01 AM by aBadScripter.)
I never did any coding for TDD (much to my regret), so I can't say how the system for SOMA compares. For trigger functions though, you want to put the name of the entity/entities that will be triggering collisions for the trigger areas in the CC_Entities field. Either put the name of a specific entity, like "meat_bag", or use a wildcard (*) to specify any entity whose name follows the pattern. For example, putting "ball*" in the CC_Entities field will cause it to trigger off of any entity whose name starts with "ball", like "ball_01", "ball_glass", or "ball_avalanche". (If you want it to trigger with the player, put "player".)
Next, you put the name of your function that will handle the collision in the CC_Funcs field, such as "ExitLevelArea_OnCollide". When you put a name, you can press the copy button to automatically put the necessary code in your clipboard, which you can then paste into your script file. The code will look like this:
asParent: The name of the area that was collided with.
asChild: The name of the colliding entity.
alState: The state of the collision. (1 means the entity entered the area; -1 means the entity left the area)
return true: If the function returns false, the area will remove this callback, meaning this function will not be triggered by any future collisions.
You had the right idea with your SlideDoor_SetClosed, but your function call syntax is off. When you call a function, you need only the name of the functions and the values that you wish to be passed. In this case, you want to pass two things - the name of the door you want to change, and whether you want it to be closed or open. The syntax would look like this:
(In case you were wondering, SlideDoor_SetClosed does have a third parameter, but by default it is set to false, which makes it into what is known as an optional parameter. This parameter "abInstant" is whether you want the door to play its closing animation [false] or if you want it to instead immediately change to its closed state [true].)
(11-02-2015, 09:05 PM)Abion47 Wrote: I never did any coding for TDD (much to my regret), so I can't say how the system for SOMA compares. For trigger functions though, you want to put the name of the entity/entities that will be triggering collisions for the trigger areas in the CC_Entities field. Either put the name of a specific entity, like "meat_bag", or use a wildcard (*) to specify any entity whose name follows the pattern. For example, putting "ball*" in the CC_Entities field will cause it to trigger off of any entity whose name starts with "ball", like "ball_01", "ball_glass", or "ball_avalanche". (If you want it to trigger with the player, put "player".)
Next, you put the name of your function that will handle the collision in the CC_Funcs field, such as "ExitLevelArea_OnCollide". When you put a name, you can press the copy button to automatically put the necessary code in your clipboard, which you can then paste into your script file. The code will look like this:
asParent: The name of the area that was collided with.
asChild: The name of the colliding entity.
alState: The state of the collision. (1 means the entity entered the area; -1 means the entity left the area)
return true: If the function returns false, the area will remove this callback, meaning this function will not be triggered by any future collisions.
You had the right idea with your SlideDoor_SetClosed, but your function call syntax is off. When you call a function, you need only the name of the functions and the values that you wish to be passed. In this case, you want to pass two things - the name of the door you want to change, and whether you want it to be closed or open. The syntax would look like this:
(In case you were wondering, SlideDoor_SetClosed does have a third parameter, but by default it is set to false, which makes it into what is known as an optional parameter. This parameter "abInstant" is whether you want the door to play its closing animation [false] or if you want it to instead immediately change to its closed state [true].)
TDD scripting was a much more... Simplified version of what SOMA's scripting is. At least at the time I had started scripting for TDD, the game had been out for a year already; so there were many tutorials on how to do pretty much everything, whereas with SOMA and this much more of a complex coding with little to no tutorials, I've been struggling quite a bit. I had many, many things down with TDD within' a few weeks. I've been looking in the game coding and I'm trying to learn some of the stuff, but there's so much code to look at that I tend to get lost. But I feel with over time, I'll get the hang of this coding.
It's really nice seeing all of this described to me in such a way that I can understand it perfectly. This test map I'm doing had been really bugging me because I couldn't find out how to do anything. I had originally protested on posting on the forums because I wanted to figure it out by myself, but eventually I gave in.
I can't thank you enough for your help, and with your amazing explanations. Thank you so much!
No problem. For sure, SOMA has been out for a little over a month, so there hasn't been a whole lot of time for people to get used to the whole bit of it. Add that to the fact that SOMA's scripting API is apparently that much harder than Amnesia's was, and you get a situation where even people with extensive experience in Amnesia's modding have little clue how to do anything.
I get the whole "wanting to figure it out yourself" thing. As a developer, there is a very fine line to walk between investing time in learning your tools and wasting time reinventing wheels. I would say though, that with SOMA being such new territory, don't hesitate to bring up questions, because chances are they are questions that haven't been asked yet around here, even if it's about a topic that seems like something simple. At this point, the community can only benefit from having its public knowledge pool increased.
(This post was last modified: 11-05-2015, 08:20 AM by Abion47.)
Hmm... so I am making a map, purely for testing, but I may release it on the workshop, the ending basically goes: use omnitool on panel, opens elevator doors, walk inside, use omnitool on another panel, but that's where I'm stuck at. How would I get the second omnipanel to close the elevator door? Either I do that or I simply use the trigger area to close the doors behind. I sort of want the screen to fade to black as well, because I think that'd suit the moment.
(This post was last modified: 11-24-2015, 05:33 AM by Hypercube.)
(11-23-2015, 11:37 PM)Hypercube Wrote: Hmm... so I am making a map, purely for testing, but I may release it on the workshop, the ending basically goes: use omnitool on panel, opens elevator doors, walk inside, use omnitool on another panel, but that's where I'm stuck at. How would I get the second omnipanel to close the elevator door? Either I do that or I simply use the trigger area to close the doors behind. I sort of want the screen to fade to black as well, because I think that'd suit the moment.
I played your map on steam. I thought it was really good.
(This post was last modified: 04-12-2016, 01:22 AM by ghoststeam217.)