View Full Version : Some questions about the Arma 2 scripting engine.
At first tnanks a lot for not banning me for questions probably already answered here on this forum. I've used search but unhopefully found nothing, so posting here.
I have got next questions during the make of my first big project:
1) How can I delete vehicle from the gameworld with the driver inside? When I use deleteVehicle on the vehicle with the driver created in the editor vehicle disappears and driver falls down. =) I want him disappear aswell.
Do the driver of the created vehicle have the same group as the entire vehicle? If so - can I delete both vehicle and driver with something like:
// If I want to delete _the_unit_to_be_deleted with the dirver inside:
_units_list = units group _the_unit_to_be_deleted;
"deleteVehicle _x" forEach _units_list;
Ore something like that. For me it did not work. =(
2) How can I create markers only visible to one side and invisible for another (multiplayer).
3) Can I create separate introes, separate briefings and objectives for different sides? (multiplayer)
and one more
4) Can I make squad-specific respawn markers? So only one group will be spawning there. And if so is there any way to grant user an ability to choose his spawn location? For exampla base or this squad-specific marker.
Maddmatt
Jun 8 2009, 23:37
The first one is easy, so I'll answer that.
Use the 'crew' command to get an array of whoever is in the vehicle.
_crew=crew myvehicle;
{deletevehicle _x} foreach _crew;
The rest gets more complex, and as I don't usually do MP stuff I'll let someone else help with that.
By the way this is the ArmA section, not ArmA 2. Maybe a mod can move this thread for you.
Edit: Looks like it was moved.
CarlGustaffa
Jun 9 2009, 04:14
Check out the Arma1 scripting topics, especially the sticky ones on the top:
Arma1 Scripting Topics (http://forums.bistudio.com/forumdisplay.php?f=70)
You'll quickly learn that scripting for multiplayer can be tricky, especially of you're new to the language and locality (http://community.bistudio.com/wiki/Locality_in_Multiplayer) issues of the commands.
2) I've never done it, as I'm into coops only. But I'll suggest downloading some Arma1 multiplayer missions and see how its done.
3) See #2.
4) As for respawn, I'd go with base respawn for each side. After respawn you can teleport the player to the position of the current leader of the squad or a location of your choosing if the position is to be dynamic.
Welcome and good luck. Jumping straight into multiplayer editing is bold :)
MemphisBelle
Jun 9 2009, 07:58
You also can take a look into Mr-Murray Editing Guide. There´s a bunch of information in it. A book for A2 will follow later but you can use it as well.
You find the book in my signature...
NeoArmageddon
Jun 9 2009, 09:16
2) How can I create markers only visible to one side and invisible for another (multiplayer).
Create the markers via script. Create them local and check the side of the player.
if (side player==west) then {
_marker = createmarkerlocal getpos westbase;
} else {
_marker = createmarkerlocal getpos eastbase;
};
3) Can I create separate introes, separate briefings and objectives for different sides? (multiplayer)
Yes , Dont Know, Yes.
For seperate intro and objective for each side just place a "sidecheck" like the markerthing in the introcamscript or the init/script that activates the objectives.
I think there was a way to make briefings for each side since OFP, but i cant remember it anymore.
4) Can I make squad-specific respawn markers? So only one group will be spawning there. And if so is there any way to grant user an ability to choose his spawn location? For exampla base or this squad-specific marker.
Place a script called onplayerkilled.sqs in your mission directory. It will execute if the player dies.
Write
waituntil {alive player};
in the script. If the player dies, the script will wait until he respawn. After that you can simply make a setpos to another location or do anything else with the repawned player.
DiRaven
Jun 12 2009, 13:19
Ou dear... Thanks for answers... Big sorry for the delay, had problems with the internet almost a week. I will check all the tips asap. Thanks again. =)
---------- Post added at 01:14 PM ---------- Previous post was at 12:25 PM ----------
Check out the Arma1 scripting topics, especially the sticky ones on the top:
Arma1 Scripting Topics (http://forums.bistudio.com/forumdisplay.php?f=70)
ou'll quickly learn that scripting for multiplayer can be tricky, especially of you're new to the language and locality (http://community.bistudio.com/wiki/Locality_in_Multiplayer) issues of the commands.
Will do. Thanks. =)
2) I've never done it, as I'm into coops only. But I'll suggest downloading some Arma1 multiplayer missions and see how its done.
Already done. Coding styles are very different. And my goal is to find good solution which will be reworked and reused, not that "copy-paste" programming.
3) See #2.
4) As for respawn, I'd go with base respawn for each side. After respawn you can teleport the player to the position of the current leader of the squad or a location of your choosing if the position is to be dynamic.
Welcome and good luck. Jumping straight into multiplayer editing is bold :)
Thanks again. =) I'm working on a huge project that looks like Domination but is more complex.
You also can take a look into Mr-Murray Editing Guide. There´s a bunch of information in it. A book for A2 will follow later but you can use it as well.
You find the book in my signature...
Downloading. Thanks.
Create the markers via script. Create them local and check the side of the player.
if (side player==west) then {
_marker = createmarkerlocal getpos westbase;
} else {
_marker = createmarkerlocal getpos eastbase;
};
Will check it out. It is the way I thought it to be done. Just expected there are already ready functions like "Add marker for OPFOR" =)
Place a script called onplayerkilled.sqs in your mission directory. It will execute if the player dies.
Write
waituntil {alive player};
in the script. If the player dies, the script will wait until he respawn. After that you can simply make a setpos to another location or do anything else with the repawned player.
Perfect tip. Thanks a lot.
---------- Post added at 01:19 PM ---------- Previous post was at 01:14 PM ----------
The first one is easy, so I'll answer that.
Use the 'crew' command to get an array of whoever is in the vehicle.
_crew=crew myvehicle;
{deletevehicle _x} foreach _crew;
Exactly what I asked. Big thanks. =)
NeoArmageddon
Jun 12 2009, 13:36
Originally Posted by NeoArmageddon
Place a script called onplayerkilled.sqs in your mission directory. It will execute if the player dies.
Write
Code:
waituntil {alive player};
in the script. If the player dies, the script will wait until he respawn. After that you can simply make a setpos to another location or do anything else with the repawned player.
Thats wrong! I forgot, that onplayerkilled.sqs just works if the player dies permanently. I just ave the problem on an own map. But there is another solution.
Write in you init.sqf:
_handlerid = player addEventHandler ["killed", {_this execVM "playerkilled.sqf"}];
This will work, like my mentioned above. Here is my "playerkilled"-script for comparision/copying:
waituntil {(alive player)};
if (side player==East) then {
player setpos getpos Jail;
} else {
_spawns=MBG_locsReal-[Logic_6];
_sp = _spawns select floor(random(count(_spawns)));
player setpos getpos _sp;
};
DiRaven
Jun 12 2009, 20:10
You also can take a look into Mr-Murray Editing Guide. There´s a bunch of information in it. A book for A2 will follow later but you can use it as well.
You find the book in my signature...
Have read this stuff hardly. Really awesome work... Covers a lot of my questions. Thanks once more.
DiRaven
Jun 13 2009, 08:04
Got next question.
While trying to execute:
for "_i" from 0 to 9 do
{
player globalChat format["%1",_i];
};
I'm always getting result as "Any"... One chat message with the ANY word. Any suggestions?
CarlGustaffa
Jun 13 2009, 08:50
Was _i initialized?
http://community.bistudio.com/wiki/private
NeoArmageddon
Jun 13 2009, 09:06
I would use .sqf with
for [{_i=0},{_i<=9},{_i=_i+1}] do {
player globalChat format["%1",_i];
};
With this method _i mussnt be initialized with private.
DiRaven
Jun 13 2009, 11:53
u mean I should write something like
private "_i";
for "_i" from 0 to 9 do
{
player globalChat format["%1",_i];
};
?
That does not work aswell.
With the following:
for [{_i=0},{_i<=9},{_i=_i+1}] do {
player globalChat format["%1",_i];
};
Getting the same:
BLUFOR Player: "ANY"
---------- Post added at 11:53 AM ---------- Previous post was at 11:05 AM ----------
Looks like foreach loop can have multiline code block only in "spawn"ed functions.
For example:
{player globalChat format["%1", _x];player globalChat format["%1", _x];} forEach _arr;
Works perfectily in init.sqf and gives perfect result.
And
{
player globalChat format["%1", _x];
player globalChat format["%1", _x];
} forEach _arr;
Does not, causing player to say just "ANY", but still works OK in the spawned function.
Is it bug or feature?
CarlGustaffa
Jun 13 2009, 21:05
Could it be that you're no longer supposed to do loops like this from within a timing 'critical' script like init.sqf? I don't know really, it just sounds like some new limitation. Did you try starting such as script from a trigger or something?
DiRaven
Jun 13 2009, 21:15
Could it be that you're no longer supposed to do loops like this from within a timing 'critical' script like init.sqf? I don't know really, it just sounds like some new limitation. Did you try starting such as script from a trigger or something?
Will try, but later. Now want to give people to test my pra-alpha version. =)
In the meantime I have another question:
How to set unit desctiption (see Editor, unit mode, unit creating/editing dialog) via script?
CarlGustaffa
Jun 13 2009, 21:35
I have no idea. In Arma1 there was no point in doing it, as you couldn't script new or changed slots (afaik). All slots had to be preplaced in the editor, where you also set your descriptions.
Can you now make dynamic slots?
You could try the 3D Editor approach, as it generates a mission.sqf. Check what commands it uses to create playable characters, and if description can be set.
DiRaven
Jun 13 2009, 22:09
As I have tried - absolutely clearly it is possible to _remove_ playable slots without players. Later will try to add some.
Still think it is now possible to add new game slots while game is already running.
Nice tip about the editor. It's still buggy and useless but there is a chance to get an answer to my question.
---------- Post added at 09:49 PM ---------- Previous post was at 09:44 PM ----------
Could it be that you're no longer supposed to do loops like this from within a timing 'critical' script like init.sqf? I don't know really, it just sounds like some new limitation. Did you try starting such as script from a trigger or something?
One more thing... I have noticed that many loop-like commands (if, forEach and so on) works only in one-row-variant in the init.sqf script.
Like:
WRONG
{
player globalChat format["%1", _x];
hint format["%1", _x];
} forEach _markers;
RIGHT
{player globalChat format["%1", _x]; hint format["%1", _x];} forEach _markers;
May be this will help me when I will get back to thet piece of code... Still not sure if it is bug or feature?
---------- Post added at 10:09 PM ---------- Previous post was at 09:49 PM ----------
And once more - quick tip. How to execute script on every machine during the MP play? Not at the start via the init.sqf but in progress.
Should it be 0:0 trigger, working for everyone? Or there is another way to do it?
One more thing... I have noticed that many loop-like commands (if, forEach and so on) works only in one-row-variant in the init.sqf script.
May be this will help me when I will get back to thet piece of code... Still not sure if it is bug or feature?
This is definately not a feature and I doubt it's broken, because that would mean pretty much none of the scripts in the game would work. The old SQS was line-based, but SQF is not. If you have a case where this is not true, please present it to us :)
DiRaven
Jun 14 2009, 13:34
I'm using SQF ewerywhere now.
Right now have checked next code:
Works fine:
for [{_x=0},{_x<=49},{_x=_x+1}] do {arr_mkr_OPFOR_possibleDeploymentLocations = arr_mkr_OPFOR_possibleDeploymentLocations + ['mkr_OPFOR_possibledeployment_' + format ["%1", _x]];}
Gives "any" value instead of _x:
for [{_x=0},{_x<=49},{_x=_x+1}] do {
arr_mkr_OPFOR_possibleDeploymentLocations = arr_mkr_OPFOR_possibleDeploymentLocations + ['mkr_OPFOR_possibledeployment_' + format ["%1", _x]];
}
File format - UTF8
Editor - NotePad++ with the ArmaEdit addon
---------- Post added at 01:34 PM ---------- Previous post was at 01:06 PM ----------
BTW multiline (/* comment */) comments do not work aswell.
DiRaven
Jun 14 2009, 22:44
Due to locality I've got another question:
1. How to execute script on the server. So I must be sure that:
- It is executed.
- It is executed by server.
2. How to do the same for the certain group of players. For example for one side, for one group, for all players. And again I must be sure that:
- Script is executed.
- Script is executed by the certain group of players.
The second to my mind can be done using repeating triggers with 0:0 area. But I have no idea how to do first one.
Worldeater
Jun 15 2009, 00:56
Your examples won't work since both are missing a semicolon after the code block.
You might want to take a look at your RPT (http://community.bistudio.com/wiki/arma.rpt) file. I guess you'll find a lot of answers in there... ;)
Edit: Are you sure you use execVM (http://community.bistudio.com/wiki/execVM) and not exec (http://community.bistudio.com/wiki/exec) to run your scripts?
DiRaven
Jun 15 2009, 06:36
Your examples won't work since both are missing a semicolon after the code block.
But examples work exactly the way I explained.
You might want to take a look at your RPT (http://community.bistudio.com/wiki/arma.rpt) file. I guess you'll find a lot of answers in there... ;)
Nothing for now. Just some missing objects.
Edit: Are you sure you use execVM (http://community.bistudio.com/wiki/execVM) and not exec (http://community.bistudio.com/wiki/exec) to run your scripts?
Why do I need to use ExecVM? I don't want this scripts run asynchroniusly and I need their result returnvalue.
And still:
Due to locality I've got another question:
1. How to execute script on the server. So I must be sure that:
- It is executed.
- It is executed by server.
2. How to do the same for the certain group of players. For example for one side, for one group, for all players. And again I must be sure that:
- Script is executed.
- Script is executed by the certain group of players.
The second to my mind can be done using repeating triggers with 0:0 area. But I have no idea how to do first one.
Due to locality I've got another question:
1. How to execute script on the server. So I must be sure that:
- It is executed.
- It is executed by server.
2. How to do the same for the certain group of players. For example for one side, for one group, for all players. And again I must be sure that:
- Script is executed.
- Script is executed by the certain group of players.
The second to my mind can be done using repeating triggers with 0:0 area. But I have no idea how to do first one.
Read this. Use the code provided there.
http://community.bistudio.com/wiki/6thSense.eu:EG#Determining_if_machine_is_Ingame_Server.2C_Ded_Server.2C_Player_or_JIP_Player
Why do I need to use ExecVM? I don't want this scripts run asynchroniusly and I need their result returnvalue.
This is why
exec
exec starts a thread for a script in SQS syntax.
and
The old SQS was line-based, but SQF is not.
So, you are running SQF with an SQS command. So, your multi-line code is not being parsed properly and is giving you problems.
DiRaven
Jun 15 2009, 08:23
Read this. Use the code provided there.
http://community.bistudio.com/wiki/6thSense.eu:EG#Determining_if_machine_is_Ingame_Server.2C_Ded_Server.2C_Player_or_JIP_Player
Done, thanks. This worth trying.
So, you are running SQF with an SQS command. So, your multi-line code is not being parsed properly and is giving you problems.
And what about init.sqf then?
Hard to say without seeing what you are trying to do.
How and where was _arr declared? Is it populated with values before you try and access it? What kind of values? Where are they taken from? etc etc
NeoArmageddon
Jun 15 2009, 11:39
And what about init.sqf then?
init.sqf is executed as sqf but every .sqf script that is executed via exec wont run correctly... Thats the reason why you foreach dont run in more than one line.
DiRaven
Jun 15 2009, 12:44
This could be true. Thanks. =) And what about executing command on every computer? I mean for example setMarkerColorLocal "The marker is only modified on the computer where the command is called. " while game already started (so not using the init.sqf).
NeoArmageddon
Jun 15 2009, 15:15
For markers there is a nice solution:
If (isserver) then {
_marker setMarkerColor [0,0,0];
};
SetMarkerColorLocal is Local and SetMarkerColor is global... it can be executed on every client/server. Maybe you want to mark every players position: Just run a Loop in the init.sqf, that makes a "_playermarker setmarkerpos getpos player;".
For executing other scripts on every client, you can make a publicvariableeventhandler.
This handler is executed if a variable was changed over a publicvariable "variable" from another client.
Write in the init:
"startMyScript" addPublicVariableEventHandler {execVM "myscript.sqf";}
If a client changes the variable startMyScript and sends it via
publicvariable "startMyScript";
the script "myscript.sqf" is executed on every OTHER client.
The handler wont fire on the client, that have send the publicvariable...
A solution for this is:
startMyScript=random 1.0;
publicvariable "startMyScript";
execVM "myscript.sqf";
DiRaven
Jun 15 2009, 16:26
...addPublicVariableEventHandler...
Perfect! Exectly I've searched for! =) Thanks!
...
the script "myscript.sqf" is executed on every OTHER client.
The handler wont fire on the client, that have send the publicvariable...
A solution for this is:
startMyScript=random 1.0;
publicvariable "startMyScript";
execVM "myscript.sqf";
A quick question about this.
Will that script also run on the server? I am assuming yes, but you specifically said client.
NeoArmageddon
Jun 15 2009, 20:28
Yes, it runs on server too, if its initalized in the init.
With this you can make the server take control of the clients.
Just make a
if (isserver) then {
startMyScript=random 1.0;
publicvariable "startMyScript";
execVM "myscript.sqf";
};
Now the server take control of executing the myscript.sqf on the clients (and runs it in the server too).
This gives you also the ability to store data like scores, objectives, units, cash etc on the server.
DiRaven
Jun 16 2009, 14:24
Can I place transparent (invisible) _area_ markers (not "icon" ones) on the map?
You can modify their alpha value on mission initialization to make them invisible.
ie:
in init.sqf
"area" setMarkerAlpha 1; //visible
"area" setMarkerAlpha 0; //invisible
1 makes the marker fully visible, 0 makes it invisible. Says it is propagated across the network as well, if you want it local use the setMarkerAlphaLocal command.
Links:
http://community.bistudio.com/wiki/setMarkerAlpha
http://community.bistudio.com/wiki/setMarkerAlphaLocal
DiRaven
Jun 16 2009, 18:44
Perfect thanks. Will use it. =)
Next: How to get full list of the created unit groups?
Update: OOps. Sorry, already found.
http://community.bistudio.com/wiki/allGroups
CarlGustaffa
Jun 16 2009, 22:19
setMarkerAlpha? Holy crap that's going to be extremely useful!!
DiRaven
Jun 19 2009, 09:40
1. Does addPublicVariableEventHandler work on JIP players? (wiki comment says no, but I'm still not sure)
2. Where the trigger "On activation" statement executed? On the server or on comuters, to which units-trigger-activators are local? (May be "on activation" for triggers created via init.sqf or created on every machine (including server) fires there it was created?)
addPublicVariableEventHandler doesn't handle JiP afaik, from my experience on A1, it never got triggered on another player that joined mid game.
Triggers are executed on both clients and server, if you want to restrict the execution then you've got to use some statement like IsServer or Local Player
DiRaven
Jun 19 2009, 10:10
If I addEventHandler "killed" twice will the new one replace old one?
Nope. they'll be differentiated.
DiRaven
Jun 19 2009, 13:03
[/COLOR]
Nope. they'll be differentiated.
Roger. Perfect. Thanks. =)
Is it possible to work with the objects other types using their names as string datatype?
Like
"trigger_name" setTriggerArea [_a, _b, _angle, rectangle];[COLOR="Silver"]
NeoArmageddon
Jun 19 2009, 20:26
Trigger and marker must be used as strings.... (i hope i understand your question).
"triggername" blablabla
"marker" setmarkerpos blabla
DiRaven
Jun 20 2009, 07:51
Thanks, this worth trying.
Can I remove PublicVariableEventHandler added by addPublicVariableEventHandler? Or replace it?
DiRaven
Jun 20 2009, 12:42
How can I access objects with the object id (taken from the editor) with script?
---------- Post added at 12:42 PM ---------- Previous post was at 11:10 AM ----------
_position = getPos object94935;
hint format["%1", _position];
Gives me nothing but "array".
NeoArmageddon
Jun 20 2009, 14:09
_nObject = position player nearestObject 123456
http://community.bistudio.com/wiki/nearestObject_id
DiRaven
Jun 20 2009, 19:23
Will try it, thanks.
DiRaven
Jun 21 2009, 11:00
How to make unit get into the house by the waypoint via script?
I've tried something like:
_group = ["GUER_soldier_AKM", position player, 0] call mbLogics_CreateUnitsGroup;
_waypoint = _group addWaypoint [_pos_house, 0];
_waypoint waypointAttachObject 94935;
_waypoint setWaypointHousePosition 5;
But this does not work properly.
DiRaven
Jun 21 2009, 15:29
In addition:
Should I load any file/run any function before I am able to use BIS_fnc_taskDefend function?
The problem is in my scripts functions BIS_fnc do not work for some reason.
The code
[getPos player, side player, (configFile >> "CfgGroups" >> "West" >> "USMC" >> "Infantry" >> "USMC_InfSquad")] call BIS_fnc_spawnGroup;
Does nothing.
And
hint format ["%1", BIS_fnc_taskDefend];
Says me "any" which makes me thing that the function is not loaded.
Any suggestions?
PS: Waypoint question is still actual.
DiRaven
Jun 22 2009, 16:40
Sorry for upping but still actual...
NeoArmageddon
Jun 23 2009, 06:37
In addition:
Should I load any file/run any function before I am able to use BIS_fnc_taskDefend function?
Any suggestions?
PS: Waypoint question is still actual.
Try to place the function module... you can find somethink similar unter F7 (Modules).
With the Waypoints a cant help you.
DiRaven
Jun 23 2009, 09:28
OMG... I feel so stupid.
This works! Results are awesome! Thx again, Neo. Big thx. =)
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.