Frictional Games Forum (read-only)

Full Version: [HPL3 WIKI] What kind of tutorials/pages would you like to see?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5 6 7
(10-06-2015, 01:00 PM)spiritofvale Wrote: [ -> ]Hey Romulator,
how much progress have you made with simple terminals? Because I've started to figure some of it out
If you havent started the wiki page for them yet is it cool if I do when I'm done my experimenting?

To clarify, I've figured out image layering, screen positioning, item coloring, item scaling, image and text, and running a single dedicated app. I have a pretty good idea on how to run multiple apps at a time though, so I think I've figured out most of what the average modder needs for their maps.

I have not started yet, since I am writing up the other tutorial I'm working on right now - so go right ahead! I'll update the OP when your page goes up as well Smile
Alright, thanks!
Expect a page at sometime tomorrow just so I can finalize the basic stuff.
Any chance you guys will look at the elevator? I want to make a simple elevator between 2 floors but the script and the map itself in theta is so confusing, I figured out how to move the elevator but then there's things like it needs to start slow, the door needs to close, etc.

The base map has a bunch of areas, a second elevator literally on top of another and.. I just don't know Tongue

The basic idea behind what I want is basically:
  • Player opens the elevator and enters
  • Players chooses on a terminal which floor he want to move to(But just a button for now is fine since a GUI terminal takes a bunch of work by itself)
  • Elevator door closes before moving the elevator
  • Elevator starts slowly into the direction of the next floor
  • After a slow start the elevator moves quicker
  • Just before arriving it slows down to stop and after it stops the elevator door opens
  • When the player exits the elevator door closes

I want to be able to repeat that process going up and down between 2 or more floors.
Would this be really difficult to do? Would the slow start/stop make it too difficult?
I hope you guys can help me out with this because the base map doesn't exactly help me, especially since it works different(Elevator breaks and you have to get out)
I have an idea how to do it. I'll take a look later for you. Smile I'll add it to the OP so I don't forget~

New page up. https://wiki.frictionalgames.com/hpl3/co...r/monsters

OP Updated.
New page about changing Player Properties: https://wiki.frictionalgames.com/hpl3/co...properties

I finally discovered how to change the lean function! Angel I would like to share it with you guys so I hope you enjoy!
Just a note:
I've created a "Scrappbooks" section for people who have some info on various aspects of the game/engine/tools, but feel that they don't have enough to create a proper wiki page, or are uncertain if what they have is entirely correct. Place this info there, rather than let it slip away. We can organize it later, as we collect more.

See the thread here.
Thanks Cthulhu, I have updated the OP to include your page; as well as DoctorPoo's Player Mechanics and vale's GUI terminal (WIP) page.
(10-06-2015, 02:08 PM)Romulator Wrote: [ -> ]I have an idea how to do it. I'll take a look later for you. Smile I'll add it to the OP so I don't forget~

New page up. https://wiki.frictionalgames.com/hpl3/co...r/monsters

OP Updated.

Nice tutorial.

Given this is for beginner's though, I think you should have showed the basic pathfinder_track_add setup instead, where you just write a list of all pathnodes you want your monster to follow. ex:

Pathfinder_Track_Add("Test_Monster","PathNodeArea_6",1,4);
Pathfinder_Track_Add("Test_Monster","PathNodeArea_18",1,4);
Pathfinder_Track_Add("Test_Monster","PathNodeArea_62",1,4);

While requiring more typing this setup is simpler to understand and avoids beginner's needing to learn for loops and pathnodes scripting at the same time. It's also a little bit more flexible to use this method, since you can place nodes without worrying about number, and when wanting to change a node in the middle of the track, you only have to type in the number of that node, while the for loop setup requires changing both the number of the new node and the old node so they dont overlap.

Both setups have their advantages, but given the list setup is simpler it is easier to learn first, while the for loop setup could be included as an extra.

You writing these tutorials is something I really appreciate so I hope you dont take offense from my suggestion.
I'll change it now Mug. I did link appropriate pages to try and help, but I'll fix it up now.

And don't worry, I'm too heavily optimistic to take offense Smile Feel free to say whatever~
Yup, pretty cool tutorial. Big Grin
About your comment regarding the "class cScrMap : iScrMap { /* code */ }" thing:

It's a declaration of the class that represents the map (cScrMap), and inherits stuff (like functions) from another class (iScrMap).

A class is basically a user-defined type: but, what that means in essence is that it's a way to group some data and functions related to that data together. And it really is a type, just like int, double, bool, etc. (except it's usually somewhat more complicated).

So you could have (and in SOMA, you do have) classes that represent the map, the player, monsters, lights, sound entities, or things like geometrical vectors, or even some more abstract stuff like data associated with an event, and more.

And like with other types, you once you have a class, you can create variables of that class (type).
(There's a slight technical difference in that you need to know when to use the "@" character in declarations, but the basic principle is the same.)
Just as you would declare integers using:
Code:
int a;
int b;
// etc...


You would declare custom types (classes) using:
Code:
className variable1;     // or rather:  className@ variable1;
className variable2;     //           (but forget about that @ thing for now)
// etc...

The values stored in different variables are known as different instances of the class. We also call them objects (of the class). So, one class (custom type), but many different instances (objects) of that class - which means that a monster class can represent many different monsters, or one switch class can represent different door switches on the level. Classes define the shared behavior (functions), and once you create objects, you can parameterize them with different data (e.g. hook up each switch object to a different door, etc.)

For an example of how to use classes and objects, take a look at this code snippet from the first level (slightly modified):

PHP Code:
for(int i 0mvSounds.length(); ++i)
{
    
cSlideShowSoundnextSound mvSounds[i];
    if(
mfSlideShowTimer nextSound.mfStartTime)
    {
        
// (some stuff here omitted...)
    
}


Here, cSlideShowSound is a class that (I guess) represents a sound in some kind of a slide show. Then, nextSound is a variable of the type cSlideShowSound, that's initialized to the next sound within the mvSounds array.
BTW, mvSounds is just an array of objects of type cSlideShowSound, declared earlier as:
array<cSlideShowSound> mvSounds;

Basically, just a sequence of sound objects in memory, kinda like this:
[sound0][sound1][sound2][sound3][sound4]

You use arrayName[index] to access the element at a given index, where "index" is just a number that marks the position in the array - first element being 0, second 1, third 2, etc...

So, what the code above does, is it loops through each possible index in the mvSounds array, and then it initializes the nextSound object to the element at index i.

Then it checks if some timer value is less then the start time associated with that particular sound.
That's what the nextSound.mfStartTime does - it returns data associated with that particular sound object (that was set to some value somewhere earlier, either by a scripter, or by the game itslef).

Data and functions that belong to an object/class are called class members (member variables, member functions). And you use the . syntax so access them.
objectVariableName.memberVariableName
objectVariableName.memberFunctionName(... parameters, if any ...)

For example,
mvSounds.length()
calls a member function that returns the length of the mvSounds array.

You can also do something like this:
int soundsArrayLength = mvSounds.length();

So, it's just like calling a regular function - except that it has this extra bit in front.

Finally - a note about two different ways to work with classes / objects. First, you can use existing classes, and objects of those classes - and that's what I've been talking about so far.

Second, you can create your own class definitions. Within the class itself, you call it's own (or inherited) functions without specifying an object - just your standard function call.
And that's exactly what you are doing with cScrMap.

Except that these map classes are somewhat special, since (I think) that it's the engine that finds the correct one and creates an instance - end executes the code in your map class by calling some functions that it expects to find in there.
The " : iScrMap" bit is related to something called inheritance. In short, when your class inherits from another class (known as base class, or parent class), it "inherits" stuff that's defined in the parent class.

So, this means that if you have an object of type cScrMap, you can use the member access syntax (the ".") to call functions declared in iScrMap (or, if scripting "within" the cScrMap class itself - as you normally do with user-map classes, you can just call the base class function as any other "normal" function).

Speaking of that, iScrMap just defines two functions, and one member variable:
PHP Code:
class iScrMap
{
    
cLuxMapmBaseObj;
    
    
void SetupBaseInterface(cLuxMap @aObj){@mBaseObj aObj;}
    
cLuxMapGetBase(){ return mBaseObj;}


This is done as a means to provide the user-created cScrMap class with the "core" map object exposed from the engine itself (here, mBaseObj - that should be accessed using the GetBase() function).
This "core" map object is of type cLuxMap, that can be found in hps_api.hps.
It exposes a bunch of useful functions that allow you to manipulate the map in some way.

However, FG has implemented a bunch of these helper functions that work with these classes and objects internally, and so effectively hide these details, making the scripting feel more like it did for Amnesia.

For example - there's this function that you can call in your map class like this: Map_SetDisplayNameEntry("some text");

But here's the implementation of that function:
PHP Code:
void Map_SetDisplayNameEntry(const tString&in asNameEntry)
{
    
cLuxMappMap cLux_GetCurrentMap();
    
pMap.SetDisplayNameEntry(asNameEntry);


Internally, it works on a cLuxMap instance.
Which means that you can achieve the same thing by doing this instead:
GetBase().SetDisplayNameEntry("some text");

Phew! That took waaay longer than I anticipated Big Grin.
But I hope it made some things more clear then before (although, I'm sure it's also confusing since there's a loot of new stuff here - but, it'll make more sense in time).

P.S. I guess this should probably end up somewhere in my Scrapbooks section...
Pages: 1 2 3 4 5 6 7