BF Conditionals

 

I've found that using of condtional statement is very useful in many areas. They are already used to restrict running the strategic AI to servers and setting up the flag bases correctly for CTF games. I have found a few other uses for them.

Here is an example of altering the strategic AI of a map that already has SP support without breaking online gaming. If you alter the AI on a map that is in circulation, it well CTD when you try to connect to a game server. The way around this is to ask the game engine what type of game is being played and run the appropriate scripts. This is how it's done:

Unpack the map and goto the maps root folder (Bf1942\Levels\<map name>).
Make a directory called aisp in the root folder. The path should look like this:

Bf1942\Levels\<map name>\aisp

And copy all 4 of the files in the ai directory into it. Here are the names of the files you copy from the ai folder:

Conditions.con
Prerequisites.con
StrategicAreas.con
Strategies.con

Then open the AI.con file and replace these lines:

...
run ai/StrategicAreas.con
run ai/conditions.con
run ai/prerequisites.con
run ai/Strategies.con
...

With this:

Var v_gamemode

game.gameMode -> v_gamemode

if v_gamemode == GMSingle
run aisp/StrategicAreas.con
run aisp/conditions.con
run aisp/prerequisites.con
run aisp/Strategies.con
else
run ai/StrategicAreas.con
run ai/conditions.con
run ai/prerequisites.con
run ai/Strategies.con
endIf

Once this is done, you can enhance, mangle and edit the files in the aisp folder all you want and still connect to COOP game servers with the map. Any changes you make to the scripts in the aisp folder are restricted to SP. COOP games will run the original strategic AI code.

Here are some things to note about variables, constants and conditions.

1) You must declare a variable or constant before you can use it.

2) All vaiables start with: v_

3) All constants start with: c_

4) Only variables, constants, numbers and strings can be used in conditional statements. This does not work:

if game.gameMode == GMSingle
...
endIf

5) Variables and contants can be initialized when they are declared:

Var v_isfive = 5
Const c_mynick = "Four Cents Shy"

6) Variables and constants can be substituted for command paraameters, but not the commands themselves. This works:

Var v_aggr = 0.9
aiStrategy.aggression v_aggr

But this does not

Var v_com = TimeLimit
aiStrategy.v_com = 120

7) Only 2 forms of the if statement are allowed:

Var v_yes = 1
if v_yes
...
endIf

And

Var v_value = 5
if v_value == 5
...
endIf

8) Only the == works with the if statment. Thankfully there is a set of utilities for more complex conditions:

Utils.expr
Utils.getV3X
Utils.getV3Y
Utils.getV3Z
Utils.mathExprF
Utils.mathExprI
Utils.mathExprV2
Utils.mathExprV3
Utils.mathExprV4
Utils.modl
Utils.setV3X
Utils.setV3Y
Utils.setV3Z

I use the Utils.expr the most. It will evaluate an expression and return a 1 or 0 when the expression is true or false. Here is an example of how to use it. I have a script that I add to maps to fix bad vehicle code. The Pak40 is not in all maps so I test for it before applying the fix:

Var v_info
Var v_exists
objectTemplate.info Pak40 -> v_info
Utils.expr v_info != "No object template" -> v_exists

if v_exists
... fix the code
endIf

The Utils.expr command will accept all these as the second parameter:
== != > < >= <= &|

Conditional statements have much great potintial and are not well used. For instance, it's possible to create one map that works for many different mods by using this to run the correct scripts:

Var v_gamename
game.customeGameName -> v_gamename

if v_gamename == "BF1942"
... run code for bf
elseIf v_gamename == "XPACK1"
... run code for RrR
elseIf v_gamename == "XPACK2"
... run code for SW
elseIf v_gamename == "DesertCombat"
... run code for DC
endIf

I'm still exploring thru the commands. I've found many that provide very useful information. Out of the almost 2000 commands available to the game engine, a little over 500 are actually used in creating maps and mods. I've compiled a List Of BF Commands using the debugger for those who would like to take a look at them. Almost 3/4 of these commands are used to develop and debug maps. You can use the debugger to find out more about them.

 

 

Yep, this is really good code. I used some of this to fully integrate FHX into Forgotten Hope. Problem was there is code in Forgotten Hope that breaks bot support, but I couldn't just remove it since it was needed for conquest mode. So instead I did the following:


CODE


Var v_playmode

game.gamePlayMode -> v_playmode

if v_playmode == GPM_COOP

... coop only code ...

else

... code for all other modes

endIf



Unfortunately this doesn't work for skirmish mode as Muzzi discovered, so we changed it as follows:

Firstly a file called is_coop.con was created in the game.rfa, it contains the following code:


CODE


Var v_mode
Var v_playmode

game.gameMode -> v_mode
game.gamePlayMode -> v_playmode

echo False -> v_is_coop

if v_mode == GMSingle
echo True -> v_is_coop
endIf

if v_playmode == GPM_COOP
echo True -> v_is_coop
endIf



Now, when you want to run code for coop or skirmish mode only, you do the following:


CODE


Var v_is_coop
run bf1942/game/is_coop.con

if v_is_coop == True

... Coop/Skirmish only code ...

else

... Code for other game modes ...

endIf



Note that you may need to provide a full relative reference to the is_coop.con file for the run statement, or enclose the run statement with console.useRelativePath statements as follows:


CODE


console.useRelativePaths 0
run bf1942/game/is_coop.con
console.useRelativePaths 1



As FourCentsShy pointed out, there are a ton of functions in Battlefield you could use with if statements, but you should be careful because not all data is shared across the network between client and server.

For instance I tried to create a level that would change spawns, out of bounds and statics depending on the max players setting in the server. So I used game.maxNrOfPlayers and ran different level files depending on the number of players. Unfortunately if a client has a different value in their configs, then the game will use that when connecting to the server and you'll either get a data differs from server error, or the map will be very screwed up for the client.

Same deal for trying to create a customized config file for a mod. You can't just create variables and expect them to be sent over the network to the clients, it doesn't work.

Still, lots of possibilities.

 

 

great stuff, 4Cshy, thank you so much!!
but unlike you said, the if statement supports the following operators for integer comparition:
<
>
==

next thing, i changed your code a little bit, hdm smile.gif

CODE

Var v_mode
Var v_playmode

game.gameMode -> v_mode
game.gamePlayMode -> v_playmode

if v_mode == GMSingle
echo True -> v_is_coop
elseif v_playmode == GPM_COOP
echo True -> v_is_coop
else
echo False -> v_is_coop
endIf


oh, and i forgot to thank you too!

 

It's good to see people contributing to this. Thanks C.ZI for correcting me. I learned something new. I could have sworn that I tried every combination. LOL! I guess not. rolleyes.gif

Edit: I was just wondering. Has anybody tried using the while ... endWhile statement for anything useful? I tried it once just for fun. I used it to augment the damage system ingame with the console.bindKeyToConsoleScript command. It was fun going after a tank with my knife and winning.

QUOTE (C.ZI @ Sep 16 2004, 11:54 AM)

CODE

Var v_mode
Var v_playmode

game.gameMode -> v_mode
game.gamePlayMode -> v_playmode

if v_mode == GMSingle
echo True -> v_is_coop
elseif v_playmode == GPM_COOP
echo True -> v_is_coop
else
echo False -> v_is_coop
endIf


I'm not 100% sure that will work. I know it looks cleaner but I set it up the other way because I was having problems with invalid statements if one of the game variables wasn't set (such as when playing skirmish, gamePlayMode was not set). So my concern is that if one of the statements is invalid, then the v_is_coop variable will not be properly set. Still if it works, then go for it.