Jump to content
Sign in to follow this  
dmarkwick

Question of includes, defines, and usage of

Recommended Posts

In my config, I have a line that says

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

#include "\dta\DMSmokeEffects_config.hpp"

and in that file are a number of defines, like this one:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

#define DMSmoke_Lifetime_Particle 0.3

Now, in my script, I try to use DMSmoke_Lifetime_Particle but cannot get any useful value out of it. When I try to Hint it's value up on the screen it just throws up gibberish, exactly as though the variable does not exist.

Q: What incredibly nooby thing am I doing wrong? smile_o.gif

Share this post


Link to post
Share on other sites

the #defines wont "leave" their files,so thats why they dont defined in your example. But it works the other way around, for example:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">#define DEF VAL

#include "FileName"

in this example the #define is also defined in the file that gets included

Share this post


Link to post
Share on other sites

Erm so... I #define each one twice, and they will become usable to me in script? As well as configurable from the dta folder? That doesn't sound likely to me, however I will try it out smile_o.gif

Also, as I understand it using #include is a way to make all included files act as though they WERE the same file?

Share this post


Link to post
Share on other sites

#defines, #includes, and other stuff with # in front of it is what is called a "preprocessor instruction".

The preprocessor is run over your config before it is loaded into the game (either by the cfgConvert tool when making the pbo, or else by the engine when loading the pbo).

Basically, the preprocessor takes your file, does some stuff to it, then hands the modified file to the game. So the game has no idea about any of those preprocessor instructions, as they aren't saved anywhere.

Think of the preprocessor as a big find/replace/cut/paste program that runs on your file, before the file is handed to the game.

In your case, it first finds the #include, and pastes the file "\dta\DMSmokeEffects_config.hpp" into your config where the #include is.

For #defines, the preprocessor just does a find/replace in the file.

In your example, the preprocessor finds "DMSmoke_Lifetime_Particle" and replaces it with "0.3".

You can also use the preprocessor on scripts. So you can #include that exact same file into your scripts that you are #including into your config. Then all the #defines will work in your scripts as well. Note that the #included file MUST BE PRESENT in your pbo for this to work!

Note this only works if you use the "preprocessfile" or "execVM" instructions (NOT with exec or loadfile).

You already have been using the preprocessor in your scripts if you have any comments (// or /*) in them.

Share this post


Link to post
Share on other sites

Basically, you can't use a value defined in a config by #define as a constant in a script. You can read a value out of the config (ArmA has the commands to do it, I've not tried it myself though), or you can just put the appropriate number into your script. smile_o.gif

Share this post


Link to post
Share on other sites

Canukausiuka is correct.

You need to do this.

1) Introduce a new config value.

Quote[/b] ]class CfgAmmo

{

class BulletCore;

class BulletBase: BulletCore {DM_lifetime_particle = DMSMOKE_LIFETIME_PARTICLE;};

Common practice is to write define values all uppercase.

2) Assign the new config value a value with your define in your

external config file.

Quote[/b] ]#define DMSMOKE_LIFETIME_PARTICLE 0.3

3) You can read the config values with these:

http://community.bistudio.com/wiki/getText_config - See also part.

Like

Quote[/b] ]_value = getNumber (configFile >> "CfgAmmo" >> "BulletBase" >> "DM_lifetime_particle");

---

However you better describe what you really want to do.

As i think there are better ways to do that if my guess about

your plan is correct.

So reveal it please. smile_o.gif

Share this post


Link to post
Share on other sites

Heh, thanks all smile_o.gif some good info, if a little confusing sometimes. I guess it comes into the domain of *actual* programming practises rather than scripting eh?

Q, you probably do have an idea of what I'm trying to do wink_o.gif I'm trying to have an editable file in the ArmA\dta folder that people can set to values they'd like to see DMSmokeEffects use rather than default. The example of having DMSMOKE_LIFETIME_PARTICLE = 0.3 would have each particle to have only 30% of the default lifetime, lessening the effect but increasing the performance.

What I would eventually like is for:

1. Default values to apply if NO file exists in \dta folder.

2. Edited values to apply if a file DOES exist in \dta folder.

3. MP settings to get their values from the server's settings.

I guess this question will get #2 to work, which will be good enough for a beta release.

Share this post


Link to post
Share on other sites

if I am not wrong this should work:

configuration file:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_val1 = 0.6;

_val2 = 1.0455;

_pi = 3.1415;

...

and in the script that use these values:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">#include "configFile"

_lifeTime = _val1;

Make sure the script gets loaded with preprocessor. This is the case for preprocessFile, execVM and spawn I think.

Share this post


Link to post
Share on other sites
Canukausiuka is correct.

You need to do this.

1) Introduce a new config value.

Quote[/b] ]class CfgAmmo

{

class BulletCore;

class BulletBase: BulletCore {DM_lifetime_particle = DMSMOKE_LIFETIME_PARTICLE;};

Common practice is to write define values all uppercase.

2) Assign the new config value a value with your define in your

external config file.

Quote[/b] ]#define DMSMOKE_LIFETIME_PARTICLE 0.3

3) You can read the config values with these:

http://community.bistudio.com/wiki/getText_config - See also part.

Like

Quote[/b] ]_value = getNumber (configFile >> "CfgAmmo" >> "BulletBase" >> "DM_lifetime_particle");

No no no! You don't need to do that!

You can use #defines in scripts, just like you can in configs.

So, all you have to do, is move your #defines to a different file from your config and scripts.

Then you #include that file in BOTH your config, and your scripts. So now all files get the same defines.

This way, you only have to edit one file, rather than many. This also means you don't have to have the script read from configs, which makes it faster and also can reduce bugs.

I use this all the time with dialogs. You can use #defines for the IDCs, and use those same defines in your scripts. That way you don't have a bunch of hard-coded numbers in your scripts where you don't really know what they refer to.

I'll give you an example:

myheader.hpp:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

#define SOMETHING 1

#define SOMETHINGELSE 2

//...and so on

config.cpp:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

#include "myheader.hpp"

//continue with your config, using the #defines from "myheader.hpp"

myscript.sqf:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

#include "myheader.hpp"

//continue with your script, using the #defines from "myheader.hpp"

----------------------------

In your case, you want the #include file to be external to your pbo, which holds the config and the scripts. To do this, put a \ in front of your path. For example:

#include "\myheader.hpp"

This will look for "myheader.hpp" in the SAME FOLDER as your arma.exe.

#include "\somefolder\myheader.hpp"

This will start in your arma.exe directory, then go into the folder "somefolder", then look for the file "myheader.hpp"

-----------------------

Quote[/b] ]What I would eventually like is for:

1. Default values to apply if NO file exists in \dta folder.

2. Edited values to apply if a file DOES exist in \dta folder.

3. MP settings to get their values from the server's settings.

Unfortunately, this is not so easy. If you try to #include a file that doesn't exist, the game will crash. And there is no way to test for the presence of a file before issuing the #include statement.

As far as configs go, there is no way to make 'dynamic configs' that I know about. The values are "set in stone" the moment arma is loaded.

Scripts are obviously much different and can easily be changed on the fly, but I'm not sure if you can check for a file's existence (via loadfile / preprocessfile) without an error popping up.

-------------------

If you are feeling experimental, I do know that it is possible to use variables in description.ext resources. The same might be true for configs. An example line in description.ext:

height = @myvar;

In this case, the game will read the value of the global variable "myvar" and use it as the height. In this way you can change cut resources dynamically. I do not know if this works for configs as well.

Share this post


Link to post
Share on other sites
Quote[/b] ]I'm trying to have an editable file in the ArmA\dta folder that people can set to values they'd like to see DMSmokeEffects use rather than default. The example of having DMSMOKE_LIFETIME_PARTICLE = 0.3 would have each particle to have only 30% of the default lifetime, lessening the effect but increasing the performance.

A said before, you can't directly test for the existance of a file. One method might be to use stringtables in the mission folder?

For example if someone wants to overwrite the default value for DMSMOKE_LIFETIME_PARTICLE, they would add this to a stringtable in the mission folder:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">STR_DMSMOKE_LIFETIME_PARTICLE,0.3,,,

In your code you would have this:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">//See if there is an entry in the string table

_NewValue=Localise "STR_DMSMOKE_LIFETIME_PARTICLE";

If (_NewValue=="") Then

       {

       //Use the default value

       DMSMOKE_LIFETIME_PARTICLE=0.7;

       }

       Else

       {

       //Use the user defined value

       DMSMOKE_LIFETIME_PARTICLE=Call Compile _NewValue;

       };

But to be honest, if your using global variables, why not just get the mission editor to set the new values using init.sqf?

Share this post


Link to post
Share on other sites

Imo:

IMO, what you need:

[*] Default Settings File in dta folder

- Can be edited for SinglePlayer

[*] Mission override file, as include in description.ext

- Can be edited for SP/MP, can be used in MP to decide settings

Can be done same as my 6thSense.eu Tracer settings, create a class and save variables and values in them, later to be read by a function

Optional:

[*] PublicVariable sent by server

Which only gets set and sent if there was nothing specified in description.ext hpp file

(This way, mission maker setting has precedence over default/server setting, but this can be turned around of course)

What you need next is a function:

- Check if mission setting overrides were set, use these settings

- else Check if server sends setting, use these settings

- else Use default settings

I can work this out pretty easily so if you need help, just hit me.

Share this post


Link to post
Share on other sites
I can work this out pretty easily so if you need help, just hit me.

Thanks for that smile_o.gif if it's pretty easy for you, I would appreciate the help. Currently the config file in \dta folder looks like this:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

//Config settings for DMSmokeEffects.

//Smoke_lifetime_Particle - The multiplier for particle lifetime, affects how long each particle hangs around.

//1 = default, less = shorter, more = longer. (1 = 100%, 0.5 = 50%, 2 = 200%)

#define DMSmoke_Lifetime_Particle 1

//Smoke_lifetime_Source - The multiplier for smoke source lifetime, affects how long vehicles burn.

//1 = default, less = shorter, more = longer. (1 = 100%, 0.5 = 50%, 2 = 200%)

#define DMSmoke_Lifetime_Source 1

//Smoke_Viewblock_Enable - Enables or disables smoke viewblock for AI.

//0 = disabled, 1 = enabled serverside only, 2 = enabled serverside and clients

#define DMSmoke_Viewblock_Enable 0

Pretty simple so far, and only 3 things to change so far, even if the last one isn't implemented just yet smile_o.gif

Share this post


Link to post
Share on other sites

Oh yeah - I'll be adding a couple of editable string variables too so people can apply effects to custom classes, for those vehicle addons that do not fall into one of the default classes i.e. MapFact helos.

Share this post


Link to post
Share on other sites

Why stringtables?

I believe it's better to use a classes system like the config and the description.ext

This way you can if needed inherit properties and build a tree as necessary. I also believe it gives a better overview.

I'll show you in the example, when I get some free time i'll send it. Probably within next few days.

Share this post


Link to post
Share on other sites

There's a strong case to made against the abuse of stringtables. The reason is that they don't correlate well to traditional programming methodologies. Yes, they can be abused to make interesting methods of managing functions and such. The #include method that the General described is much more maintainable simply for the fact that it can be standardized in a method that other developers can understand from a common standpoint.

The principle is reasonably simple, just call localize string injecting params along the way. I take issue with it solely on the basis of bad practice. Leave stringtables for what they were intended for - string management.

Share this post


Link to post
Share on other sites
Leave stringtables for what they were intended for - string management.

Amen to that notworthy.gif

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×