Turok: Dinosaur Hunter Forums!

Turok Games => Turok Dinosaur Hunter => Turok Dinosaur Hunter Modding/Mapping => Topic started by: Smoke39 on September 10, 2016, 12:29:02 AM

Title: Smoke's Modding Guide
Post by: Smoke39 on September 10, 2016, 12:29:02 AM
I decided that hiding this in my sig was a dumb idea. :b

Turok EX Modding Guide (https://smoke39.github.io/turok/)

I just updated the Getting Started guide to be a lot more detailed.  Hopefully it will better explain how things work, rather than simply throwing out instructions.

I also finally got started on the scripting reference.  Still working out how to organize things, but it's a start.

Next I'd like to write a series of tutorials for adding a weapon to the game.  A sufficiently complex weapon could walk modders through a whole bunch of aspects of the engine.  I was thinking something like a poison dart rifle or something.
Title: Re: Smoke's Modding Guide
Post by: Duke64 on September 10, 2016, 12:45:27 AM
Even I appreciate your guides dude. They can say a lot, like even if your looking at something that may be complicated you make it a little brighter for others. I can say honestly great job on these.
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on September 26, 2016, 02:57:30 AM
Just updated the guide with a ksnd reference, and a variety of other fixes and refinements.  This isn't the first update I've made, but I wanted to bring attention to it because Kaiser has his own ksnd guide on the Steam forums, but it has some errors and omissions.
Title: Re: Smoke's Modding Guide
Post by: Jay Doomed on September 27, 2016, 12:33:26 PM
Thanks for doing the guides so you know some people do look :) I would like to know which part Kaiser has wrong on his ksnd guide?
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on September 28, 2016, 08:26:49 AM
"max," "start," and "end" can be > 1.0.  Volume seems to get capped to 1.0 in the end, but you can still do stuff like max=2, start=0.5 to get there.

There's an edge case where "start" will have an effect in the "volume_envelope" block, even if "bEnableVolumeEnvelope" is 0.

When the volume envelope is enabled, "start" and "end" get scaled by "max."  When the pitch envelope is enabled, "start" and "end" will be used as-is; "max" is only used when the pitch envelope is disabled.

Basically the envelope blocks are full of quirks, so pay close attention to the details.
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on October 31, 2016, 03:47:15 PM
Just put up a pretty massive update.  The scripts section's been completely overhauled.  Almost all the native class function signatures are listed.  There's also some more general info, like areas and sectors, and how the tick rate works.  I've also tried to add links connecting related concepts, plus you can click on class names in function parameters and variable declarations to go to that class' page.

There's still a lot that needs to be tested and documented, but what's there now should make it a lot easier to get a feel for how things fit together, as well as an organized basis for further research.
Title: Re: Smoke's Modding Guide
Post by: Duke64 on November 14, 2016, 06:31:49 PM
Something seems to be wrong with your guide my friend. When I try to click on it.
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on November 14, 2016, 08:47:41 PM
Shit.  Looks like dropbox removed html rendering over a month ago.  I'm gonna have to figure out some other way to host this. :/
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on November 15, 2016, 01:38:09 PM
Moved to GitHub, updated OP.
Title: Re: Smoke's Modding Guide
Post by: Duke64 on November 16, 2016, 06:20:10 PM
Nice. Thanks man I do reference this sometimes. I even have a look sometimes for myself, if I think I could be wrong about something.
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on February 03, 2017, 06:25:54 PM
Got a start on the Levels section.  There's not much there yet, but the little bit that is there should still be useful.
Title: Re: Smoke's Modding Guide
Post by: Dinomite on February 03, 2017, 07:20:57 PM
Could you possibly port some weapon from evolution?
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on February 03, 2017, 09:46:33 PM
Someone else would have to get the models into the game, and I'm not sure anything with moving parts could be animated properly right now.  I could probably script them, though some details might not be doable.  I haven't quite managed to make a properly functioning scope, for example.
Title: Re: Smoke's Modding Guide
Post by: Mon-Ark on February 04, 2017, 01:50:25 PM
well, you can make animations with 3d modelling programs already, so theres not much need for the editor to have that. What I dont know is if the editor allows to import models and animation into wathever format the kex engine works.

If this were the case, then making it work is something that could to be done on the scripting side.
Title: Re: Smoke's Modding Guide
Post by: Dinomite on February 04, 2017, 02:31:03 PM
I want the warclub lol. Or the shotgun. The shotgun is one of the most satisfying in games.
Title: Re: Smoke's Modding Guide
Post by: Dinomite on February 06, 2017, 05:48:16 PM
Snake, where the fuck are you?
I swear hes like a ghost...
Title: Re: Smoke's Modding Guide
Post by: Gazer on February 10, 2017, 05:26:43 AM
lol at Dinomite - you should just learn a simple modeling proggie. You could be the resident modelersaurus.

Hey Smoke, how about you help me with a couple of scripts? I am bad at understanding the structure of them in general. Then when I do 'get it' I will forget again in like 30 seconds afterward.

In the 'scripts' folder in the 'main.txt' file there's an area for 'once-only' -  'GameVariables' and other simple scripts that reference main scripts in the engine. I'd like to utilize this in my mapfile but I can't understand the reference to (VARFUNC(functor.Add)); I tried checking the Angelscript forums but I don't have the time to learn it from scratch. As I noted earlier, I'm bad with basic programming syntax in general anyway.

So do you understand 'InitCustomStateVars' and 'SetStateVars' and how to add them to 'main.txt'? I just want to add particularly 1 item to my level.
Thanks, Gazer
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on February 10, 2017, 02:43:23 PM
Near the top of main.txt, after all the #includes, you'll see:

funcdef void VARFUNC(const kStr &in, const kStr &in);

This is defining a function type, named "VARFUNC," which takes two strings as parameters, and has no return type.  This allows us to pass functions of this type as a parameter to other functions.  In this case, Add() and SetValue(), in VarFunctor.  Add() is used to add new variables to GameVariables, and SetValue() is used to change the value of variables already in GameVariables.


In main(), you'll see:

SetStateVars(VARFUNC(functor.Add));

This is calling SetStateVars(), passing the Add() function as a parameter.  This is called once when the game is run, and it registers all the persistent, per-save variables.


In newgame(), you'll see:

SetStateVars(VARFUNC(functor.SetValue));

This is also calling SetStateVars(), but this time passing the SetValue() function as a parameters.  This is called every time the player starts a new game, and it resets all the persistent game variables to their default values.


The purpose of all this function passing malarky is that we can specify all the persistent game variables ONCE in SetStateVars(), rather than having to have two copies for adding and setting.

THE BOTTOM LINE is, to add your own persistent, per-save variables, just add them to either SetStateVars(), or InitCustomStateVars() (or even in a new function, and call it from SetStateVars(), however you wanna organize it).  Just use:

setFunc( "var name", "initial value" );

and it'll ADD or UPDATE your new variables, whichever is appropriate.

You can see examples of this in Turok+, where I've added a bunch of my own variables at the end of InitCustomStateVars().
Title: Re: Smoke's Modding Guide
Post by: Gazer on February 10, 2017, 06:39:43 PM
I've noticed your work Smoke! you Rock! I can't do what you do ... ha ha no way no how. My mind gets all kerplunktuated (void) Kstr #sizzledik -% 420 Lsd @boozer

Thanks - Gazer

I just looked at your examples - I am shocked. You did a lot of work Smoke. If I dig into this I will never finish a single map. I generally have to check each character that I type 3 times for syntax. And I flip letters and numbers sometimes, when I tpye. lol (this php has autocorrect damn i7 chip)
So I'm dumbfounded. Gazer
Title: Re: Smoke's Modding Guide
Post by: Gazer on February 14, 2017, 01:14:44 AM
Hey Smoke, Howzit?

Hey I posted my level without custom scripting (besides adding my mapid to the mapInfo.txt), but my level doesn't run without the developer "1" flag. Have you run across any information on what would cause that? I do have models in the game that are hakked and retextured, and then re-deposited into the game. That would be the only thing that could cause a conflict with original files. I haven't noticed any conflict though and no error messages besides game crashes at startup when developer set to "0".

Sobek.exe caused and exception - yata yata - hexadecimal code - hexa - hexa

Thanks - Gazer
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on February 14, 2017, 01:27:50 AM
My first guess would be inconsistent capitalization somewhere.  As I highlight here (https://smoke39.github.io/turok/getting_started.html), unpackaged file names are not case-sensitive, but files packaged in a kpf are case-sensitive.  E.g., having a file named "Banana.map" referred to as "banana.map" in mapInfo.txt will cause problems.
Title: Re: Smoke's Modding Guide
Post by: Dinomite on February 14, 2017, 06:58:06 AM
"Banana.map"
yes
Title: Re: Smoke's Modding Guide
Post by: Gazer on February 14, 2017, 01:33:26 PM
My best guess at this point is the models that I copied and retextured. I'm cognizant of the case sensitivity and I checked everything in that respect. So in testing my models now in controlled conditions I'm getting 'memory could not be read' crash log return. (with developer '0')

Eh - the little done, the vast undone. Gazer

EDIT: Smoke do you have anything on the hexadecimal codes?
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on February 14, 2017, 01:57:31 PM
Smoke do you have anything on the hexadecimal codes?

No.  I think that stuff's probably not of any use without a debugger and the game's source.
Title: Re: Smoke's Modding Guide
Post by: Gazer on February 14, 2017, 04:23:33 PM
I figured out the problem, 2 bad models - out of 16 total that I added. Sheesh I'm relieved it's not a bad fix. I say mapping for this thing is a real chore. I guess I'm spoiled from using Radiant in the past. There was a lot of people working on the same thing who generated a lot of solutions to problems. It's astonishing the scripting work you've done Smoke.

Thanks - Gazer
Title: Re: Smoke's Modding Guide
Post by: Dinomite on February 28, 2017, 02:23:55 PM
I figured out the problem, 2 bad models - out of 16 total that I added. Sheesh I'm relieved it's not a bad fix. I say mapping for this thing is a real chore. I guess I'm spoiled from using Radiant in the past. There was a lot of people working on the same thing who generated a lot of solutions to problems. It's astonishing the scripting work you've done Smoke.

Thanks - Gazer
What is no Ciggi?
Title: Re: Smoke's Modding Guide
Post by: raul on May 17, 2017, 11:13:46 PM
Thank you so much Smoke39, this guide is pretty handy!
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on June 23, 2017, 07:24:18 PM
Finally added an explanation of native classes (kex-prefixed), and how they work with internal script classes (k-prefixed) and user scripts (the stuff we can change): https://smoke39.github.io/turok/scripts.html#ControlStructure.  It can be kinda confusing, so I hope I was able to make things a little clearer, rather than even more confusing.

Sometime I'd like to put together a proper reference on actor defs, with info on all the native classes.  Currently you can kinda get a feel for what's delegated to the scripts by looking at the callbacks in ScriptObject, ScriptObjectPlayer, and ScriptObjectWeapon, but I think it'll help people develop an intuition seeing examples of the other side of that -- what's handled natively.
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on September 11, 2017, 07:21:05 PM
Added info on actor initialization to ScriptObject (https://smoke39.github.io/turok/ScriptObject.html), and info on the persistent bit (mostly in ScriptObject, plus some functions in kActor).
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on September 24, 2017, 02:46:01 AM
Added some info on player lock (https://smoke39.github.io/turok/kPlayer.html#Lock) as it pertains to cutscenes (https://smoke39.github.io/turok/kCamera.html#StartCinematic) and weapon state (https://smoke39.github.io/turok/ScriptObjectWeapon.html#Weapon).
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on September 25, 2017, 01:28:09 AM
Wasted a bunch of time today trying to figure out what was wrong with my math, only to eventually figure out that the "kVec3 *= kQuat" operator is broken, so I added a big ol' warning to the kQuat (https://smoke39.github.io/turok/kQuat.html#Operators) page.
Title: Re: Smoke's Modding Guide
Post by: BehemothProgrammer on September 25, 2017, 02:44:19 AM
Oh wow that sucks. I'm going to have to see if it's the same in T2 since it's pretty much the same.
Title: Re: Smoke's Modding Guide
Post by: Jay Doomed on September 25, 2017, 12:20:41 PM
Good work Smoke nice to see more helpful info keep it up.
Title: Re: Smoke's Modding Guide
Post by: DoomMarine23 on October 11, 2017, 11:38:19 AM
Assuming you're still maintaining this guide, I'm gonna dig through some of the undocumented stuff and write up some notes that hopefully will be some use.

I'll submit some github pull requests as soon as I get something worth showing. This guide is way too useful, its only fair to give back. lol
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on October 11, 2017, 07:18:20 PM
I dunno shit about using github.  I guess it'll be a learning experience. :b
Title: Re: Smoke's Modding Guide
Post by: DoomMarine23 on October 11, 2017, 08:04:52 PM
Yeah I just use the desktop application to be honest.

https://desktop.github.com/
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on December 27, 2017, 01:15:23 AM
I've discovered that values don't get loaded into GameVariables from save files unless their key had already been added to GameVariables (namely, in main.txt), so I added a note about it to the kDict reference.

While I was at it, I also finally got around to updating the kAI page with the unlisted flags that Behemoth clued me into a while ago.
Title: Re: Smoke's Modding Guide
Post by: Dinomite on December 28, 2017, 05:24:13 PM
Smoke, what drives you to put so much effort into a mod for such a obscure game? It's a good thing, but does it not bother you that there are not that many players who can enjoy your mod? (Due to the game not being that well known)
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on December 29, 2017, 12:29:35 AM
It's fun.
Title: Re: Smoke's Modding Guide
Post by: Duke64 on December 29, 2017, 12:43:39 AM
It's fun.
All Achievements Unlocked

:primagen: :raptoid: :t-rex: :chronosceptor: :feather:
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on February 05, 2018, 12:34:16 AM
Added some info to kCModel and kActor::CanSee(), based on some experiments with raycasting.  The new CModel info is from a post Kaiser made on steam a long time ago, but I tried to rephrase the function descriptions to be a little clearer now that I've finally done some actual testing.
Title: Re: Smoke's Modding Guide
Post by: Dinomite on September 03, 2018, 05:31:39 PM
Got anything else to add to the guide?
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on September 03, 2018, 06:30:20 PM
I update stuff occasionally as I refine my understanding: https://github.com/Smoke39/turok/commits/master
Title: Re: Smoke's Modding Guide
Post by: Dinomite on September 04, 2018, 03:06:35 AM
Oh, alright. :D
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on March 07, 2019, 03:25:56 AM
After a fair bit of experimentation, I think I've reverse-engineered the details of how kActor::MeleeObject() works.  I also documented kActor::InteractActorsAtPosition(), which can, for example, be used to implement custom alternatives to MeleeObject().
Title: Re: Smoke's Modding Guide
Post by: DoomMarine23 on March 07, 2019, 03:56:57 PM
Glad to see you've continued with this. When I get the time, maybe this weekend or next week, I am gonna look into documenting a few functions as well.
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on March 08, 2019, 03:16:36 AM
Clearing out a backlog of stuff I accumulated while working on my first map:

Figured out which params are which with kActor::SpawnParams().

The levels section has been massively expanded.  In addition to a bunch of handy reference info, of particular note are a couple of quirks with triggers:
1. enemy Target TID can only trigger other actors on death, not level scripts
2. event sectors can only trigger level scripts if there are no actors with a matching TID
Title: Re: Smoke's Modding Guide
Post by: BehemothProgrammer on March 09, 2019, 01:24:54 AM
Nice work listing all the attacks for all the enemies. That was something annoying I never wanted to do, but needed to lol. You pretty much got everything listed that's awesome.

Your mentioning InteractActorsAtPosition and I just wanted to show a helper function I used for calling functions from the map module to an actor in the game module, that uses InteractActorsAtPosition. This function will spawn a special actor type at the players position and set it to solid so InteractActorsAtPosition will call it. You only want the function to be called on the actor once instead of for every solid actor in range so you need to do a condition check for that actor type at the start of your function.

Code: [Select]
//------------------------------------------------------------------------------------------------------------------------
// Useful to call custom functions from the map script module to the game script module.
// Otherwise just use the ScriptObject's ScriptObject() function to get a handle to it.
//
// Required:
// Function header: void funcName(kActor @actor, const float arg1, const float arg2, const float arg3, const float arg4)
// Function body condition check: if (actor.Type() != BP_AT_FUNCTIONCALL) return;
//------------------------------------------------------------------------------------------------------------------------
void CallFunc(kActor@ actor, const kStr &in funcName, const float arg1 = 0.0f, const float arg2 = 0.0f, const float arg3 = 0.0f, const float arg4 = 0.0f)
{
kActor@ playerActor = Player.Actor().CastToActor();
kActor@ dummy = Spawn(BP_AT_FUNCTIONCALL, playerActor.Origin(), 0.0f, playerActor.SectorIndex());
dummy.Flags() |= AF_SOLID;
actor.InteractActorsAtPosition(playerActor.Origin(), funcName, arg1, arg2, arg3, arg4);
dummy.Remove();
}

and going the other way from game to map module is easy with the Game.CallDelayedMapScript function.

Here's the last of my random stuff I found out when making my last map that I don't think you have in the guide, hope it helps.
https://pastebin.com/raw/fExJrV1j
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on March 09, 2019, 03:47:09 AM
Shit, you can actually get an actor's script object from a level script?  I tried doing that while making Cliffside Outpost, and as I recall I was getting cast errors, so I thought the game and level script contexts were just so distinct that they each had their own distinct copies of classes or something.  Just did a quick test with a QuakeSource from a level script, though, and I was able to call SetupShake() and mess with its member variables, so apparently I was doing something wrong before.  Really good to know that's possible after all.

Given that, I'm not sure what the purpose of using InteractActorsAtPosition() is?  Why not just get a handle to the dummy actor's script object and call the function directly?

Thanks for the notes.  I'll parse through them eventually, but just skimming through them I'm noting some nice little nuggets. :)
Title: Re: Smoke's Modding Guide
Post by: BehemothProgrammer on March 09, 2019, 02:02:25 PM
That works because QuakeSource is a shared class. https://www.angelcode.com/angelscript/sdk/docs/manual/doc_script_shared.html

Quote
Shared entities have a restriction in that they cannot access non-shared entities because the non-shared entities are exclusive to the script module in which they were compiled.

And that's not going to work when trying to get non shared classes from the game default scripts. And also it says there that you can share funcdefs which is wrong, or the angelscript version used in the game is really old. So casting to a non shared class compiled from another module will always return null. The only way to do custom things with non shared scripts is with that helper function that's able to call a function on an actor to the game module with 4 floats that can do whatever.

In this game there are 2 modules for scripting, I'll call them the game module and the map module. https://www.angelcode.com/angelscript/sdk/docs/manual/doc_module.html
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on March 09, 2019, 04:54:25 PM
Okay, I think I understand.  I think with Cliffside Outpost I was trying to mess with movers, which aren't shared, so that would explain it.

So to answer my own question, if you wanted to get a handle to the dummy actor's script object, it'd have to be declared shared.  But if it's shared, then it wouldn't be able to interact with any non-shared entities.  So you use InteractActorsAtPosition() to interact with non-shared entities in the game module from the level module.

This may be naiive, but then why not just redeclare everything shared?  You wouldn't be able to access global variables, but those could be changed to member variables in a shared class.
Title: Re: Smoke's Modding Guide
Post by: BehemothProgrammer on March 10, 2019, 05:36:21 PM
So to answer my own question, if you wanted to get a handle to the dummy actor's script object, it'd have to be declared shared.  But if it's shared, then it wouldn't be able to interact with any non-shared entities.  So you use InteractActorsAtPosition() to interact with non-shared entities in the game module from the level module.
Right you got it.

Quote
This may be naiive, but then why not just redeclare everything shared?  You wouldn't be able to access global variables, but those could be changed to member variables in a shared class.
You could, but I don't think you really want to modify all of the game scripts for that and not be able to use global variables, funcdefs, and whatever other types it doesn't support. I wouldn't do that. You shouldn't need to communicate with the ScriptObjects directly very much or not at all from the map scripts. In the rare event you want to do more you can use that helper function, but you might want to ask yourself if what your trying to do could be done in the actors script itself.

For instance if your trying to change the water height in a special way. Then maybe you want to make an actor that handles that and changes the water height when it gets triggered some way. In the map editor you can setup the actor with all the data it needs to know what to do with those SpawnParams, and also if you don't need them for collision, you can use: Radius,Height, WallHeight, and StepHeight. And the 3 spawn flags, are all accessible. Then when the actor is triggered it'll change the water how you want it. You should try to break down all the special things you want to do in your map to generalized actors that can handle everything you want to do with a simple OnActivate call from an event trigger.

It's one of the things I did in my last map was making all those kinds of actors that I needed. An actor that spawns items in any way I want, A counter actor that increases a number and triggers an actor/script when it reaches a certain value, An FxSpawner, An EventLink for handling trigger conditions to actors/scripts, HUD Messages, Playing sounds, modifying anything about a sector/area, a collision trigger area that triggers actor/scripts when you touch it, etc... Then you start to see that you really don't even have to do any scripting in the map, but in some situations you might and that's where it can come in handy.
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on March 11, 2019, 04:34:55 AM
I know I can make new actors with custom functionality.  I was trying to avoid actor type ID collisions with Turok+, especially if I reorganize it in the future.  I guess that's kinda silly, considering there are over 4 billion possible actor type IDs, which leaves plenty of room for massive buffers between ranges of values.  I'll probably try to be smarter with my future maps. :b
Title: Re: Smoke's Modding Guide
Post by: BehemothProgrammer on March 11, 2019, 05:28:18 PM
Yeah lol you don't have to worry about that. What's weird about this game is that actors with the same type like -1, can still be spawned by it's name, and you can still access it's correct Definition. But the editor uses the type instead of the name, so if you're only using actors to spawn at runtime you can set all their types to -1. But yeah I usually just reserve 1000 ids for my mod and I know I'll never go beyond that.
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on March 12, 2019, 06:10:29 PM
Are you sure there are float versions of AddItem() and Select() for kSelectionListFloat?  I'm getting warnings about implicit type conversion when I try to pass floats to AddItem(), and when I print the result of Select() I'm not getting any decimal places.  I'm also not seeing float versions of those functions in the executable (though I'm just searching for strings in a text editor).
Title: Re: Smoke's Modding Guide
Post by: BehemothProgrammer on March 12, 2019, 08:17:40 PM
I just checked it again, and yes it looks like kSelectionListFloat is exactly the same as kSelectionListInt. :o And int& Select(const bool = false) has a bool parameter.

Some more info on map scripts. $restart remaps to
Code: [Select]
void Game.CallDelayedMapScript(const int scriptID, kActor @instigator, const float delay)
where scriptID is taken from the last $script <id> value used in the script before $restart. instigator is placed in the instigator actor arg and the delay is 0. So it's calling itself and will execute itself on the next script execution cycle (not immediately). You can do this same thing and call CallDelayedMapScript(const kStr &in funcName, kActor @instigator, const float delay) for your custom map functions in order to loop them.
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on March 12, 2019, 11:06:46 PM
I just checked it again, and yes it looks like kSelectionListFloat is exactly the same as kSelectionListInt. :o And int& Select(const bool = false) has a bool parameter.

Thanks for the confirmation.  The bool was added and the return value changed to a reference in 2.0.  Anecdotally, passing true seems to get results slightly closer to the expected values, but heck if I know what it's actually doing.

Some more info on map scripts. $restart remaps to
Code: [Select]
void Game.CallDelayedMapScript(const int scriptID, kActor @instigator, const float delay)
where scriptID is taken from the last $script <id> value used in the script before $restart. instigator is placed in the instigator actor arg and the delay is 0. So it's calling itself and will execute itself on the next script execution cycle (not immediately). You can do this same thing and call CallDelayedMapScript(const kStr &in funcName, kActor @instigator, const float delay) for your custom map functions in order to loop them.

Did some quick testing 'cause I was curious about how $restart would work in non-numbered level scripts, and inside functions called from other level scripts.  The impression I'm getting is that by "last $script used before $restart," you're talking about the actual topography of the file, not the execution order.

So for example if you had something like this:
Code: [Select]
$script 1
{
}

void Blah()
{
$restart;
}

$script 2
{
Blah();
}

and then called Game.CallDelayedMapScript( 2, Player.Actor(), 0 ), you'd get $script 2 -> Blah() -> $script 1
Title: Re: Smoke's Modding Guide
Post by: BehemothProgrammer on March 13, 2019, 04:54:56 PM
yup that's what will happen. Just have to declare a kActor@ named instigator before $restart in that example.
Title: Re: Smoke's Modding Guide
Post by: BehemothProgrammer on March 13, 2019, 06:51:06 PM
More stuff.

AAF_EVENTSOUND - (must be paired with AAF_EVENT) arg2(in editor) is to be set to the soundID defined in defs/fileLookup.txt. When the player enters the area that sound will play. Be careful though, the event in arg4 will also be executed.

-----World-----
void FloodFillAreaFlags(  int sector, uint flags, bool bSet ) - DO NOT USE!!! (Use FloodMatchingAreaFlags instead) This can only turn OFF area flags. If you attempt to turn ON any flag while that flag is already ON for that sector/area, the game will crash.

void ChangeAreaFlag( int areaID, uint flags, bool bSet ) - DO NOT USE!!! (Use FloodMatchingAreaFlags instead) Only certain flags work correctly when set. The full list of my tests is:
Code: [Select]
AAF_WATER = 1 << 0 //works, partially. No shallow water sound effects play.
AAF_BLOCK = 1 << 1 //does NOT work
AAF_TOGGLE = 1 << 2 //
AAF_CLIFF = 1 << 3 //does NOT work
AAF_CLIMB = 1 << 4 //does NOT work
AAF_ONESIDED = 1 << 5 //(Bridge) does NOT work
AAF_CEILING = 1 << 6 //does NOT work
AAF_CRAWL = 1 << 7 //works
AAF_ENTERCRAWL = 1 << 8 //works
AAF_HIDDEN = 1 << 9 //works
AAF_ENTERED = 1 << 10 //
AAF_SECRET = 1 << 11, //works
AAF_RESTRICTED = 1 << 12 //works
AAF_SLOPETEST = 1 << 13 //does NOT work
AAF_DEATHPIT = 1 << 14 //works
AAF_MAPPED = 1 << 15 //does NOT work
AAF_EVENT = 1 << 16 //works
AAF_REPEATABLE = 1 << 17 //
AAF_TELEPORT = 1 << 18 //works
AAF_DAMAGE = 1 << 19 //works
AAF_DRAWSKY = 1 << 20 //works
AAF_TELEPORTAIR = 1 << 21 //works
AAF_LAVA = 1 << 22 //works
AAF_EVENTSOUND = 1 << 23 //works
AAF_ANTIGRAVITY = 1 << 24 //works
AAF_LADDER = 1 << 25 //works
AAF_CHECKPOINT = 1 << 26 //works
AAF_SAVEGAME = 1 << 27 //works
AAF_WARPRETURN = 1 << 28 //
AAF_SHALLOWWATER = 1 << 29 //works
AAF_DRAWSUN = 1 << 30 //works
AAF_STOREWARPRETURN = 1 << 31 //


void FloodMatchingAreaFlags( int sector, uint flags, bool bSet )
void FloodFillAreaFlags( kVec3& loc, uint flags, bool bSet )

both work for all flags so use these instead.

Title: Re: Smoke's Modding Guide
Post by: Smoke39 on March 14, 2019, 03:06:22 AM
Did some more testing and found some quirks with $script 0.  Made a new level scripts section, and updated kGame::CallDelayedMapScript().  I'm not going out of my way to verbosely spell out all the preprocessor stuff with examples 'n' such since I think it's kind of academic, but I think I've got all the basic info there.

Thanks for the area flags stuff.  Those function issues are pretty big; I'll probably try to take care of them soon.
Title: Re: Smoke's Modding Guide
Post by: Smoke39 on April 19, 2019, 09:11:13 PM
Added a new tutorial on updating Steam Workshop items when the editor insists on only creating new ones, since it's a recurring issue people keep running into.  Hope it helps.
Title: Re: Smoke's Modding Guide
Post by: Dinomite on July 05, 2019, 09:35:01 AM
 :blank: