Home   Help Search Login Register  

Author Topic: MP Briefings  (Read 4271 times)

0 Members and 3 Guests are viewing this topic.

Offline CharlieReddog

  • Members
  • *
MP Briefings
« on: 22 Feb 2008, 00:23:33 »
I had a thread over on the BIS forum, but I think it's more likely to get some resolution over here. :clap:

I would like to be able to hide and reveal objectives relative to the required mission within the init or a script run from it, BEFORE the briefing is over. I would like the correct objectives and their markers etc to be showing at the map and briefing screen. At the moment, I have all my objectives showing.

A second alternative would be to be able to "pause" the game in MP, to allow the players to review the map and briefing. Is it possible to force the server to pause in MP? I'm not bothered at all, in fact I'd prefer it, if the players couldn't move at the same period. I think this is completely impossible, but just throwing it out.

Cheers,


Offline Spooner

  • Members
  • *
  • Mostly useless
    • Community Base Addons
Re: MP Briefings
« Reply #1 on: 22 Feb 2008, 11:24:39 »
I've had no problems at all manipulating objectives and markers in the briefing.

Well, when the game starts properly (i.e. the briefing is over), the game timer starts. That is, time is 0 during the briefing, however long it lasts, and starts counting up during the game. If you pause in any way during your init script before making changes to objectives and markers, for example by starting an external script with execVM or using sleep at any time, then it will wait until the timer has started, which means it will wait until the game has started running. The easiest way to do this is to ensure that no sleeps are above the code in the init file and that, if you need to call an external file with this code in, you use call compile preprocessFileLineNumbers rather than execVM to call it. You also have to be careful of waituntils, but only if they are waiting for something that won't happen until the briefing is over.

The need to pause MP shouldn't be relevant, but I'm pretty sure it is impossible in the way that you are thinking anyway. You could mimic it, perhaps, by forcing the map to be shown for a time, which would prevent the players from doing anything else, but this wouldn't stop the mission (AI, etc) from continuing in the background. Still, totally unnecessary, so it doesn't matter ;P
[Arma 2] CBA: Community Base Addons
[Arma 1] SPON Core (including links to my other scripts)

Offline CharlieReddog

  • Members
  • *
Re: MP Briefings
« Reply #2 on: 22 Feb 2008, 13:17:18 »
I set up a sample mission to test whether or not it was something that I had in one of my other scripts.

Code: [Select]
"mkr1" setmarkerpos getpos lgc_1;
"mkr2" setmarkertype "empty";
"1" objstatus "Hidden";
"2" objstatus "hidden";

Thats the code within start.sqf which I execvm'd from the init. The markers move, but the objectives 1 and 2 show until you press continue on the briefing, and then when you look at the map screen again, they have gone.

How do you do it? Are you sure you aren't hiding them within the mission?

Offline Spooner

  • Members
  • *
  • Mostly useless
    • Community Base Addons
Re: MP Briefings
« Reply #3 on: 22 Feb 2008, 13:35:23 »
I don't actually have access to my mission, or ArmA for that matter, right now, but I'm sure this works for my mission as well as others' missions.

The only thing I can suggest is to use:
Code: [Select]
call compile preprocessFileLineNumbers "start.sqf";

rather than:
Code: [Select]
execVM "start.sqf";

Since the former ensures immediate execution of the code (the external script file is run as though it were part of init.sqf, rather than by starting up an entirely new script). Still, if the marker changes are being seen correctly in the briefing, but the objective changes aren't, that seems odd, and possibly nothing to do with this call/execVM issue. *shrugs*
[Arma 2] CBA: Community Base Addons
[Arma 1] SPON Core (including links to my other scripts)

Offline CharlieReddog

  • Members
  • *
Re: MP Briefings
« Reply #4 on: 22 Feb 2008, 19:58:29 »
You sir are a genius. It works great. now I just need to convert my file from sqs into sqf for the real thing.

"Start.sqf" actually triggers another sqs file, which strictly speaking isn't necessary to have in a separate file.

Offline CharlieReddog

  • Members
  • *
Re: MP Briefings
« Reply #5 on: 22 Feb 2008, 21:32:05 »
Run into a little problem converting to sqf.

Code: [Select]
if (_N>=0.5) then {_N=1} else {_N=0};
if (_E>=0.5) then {_E=1} else {_E=0};

if (_N==0 and _E==0) then {
_loc= "NE";
}
else
{
if (_N==1 and _E==1)then {
_loc= "SW";
}
else
{
if (_N==0 and _E==1)then {
_loc= "NW";
}
else
{
if (_N==1 and _E==0)then {
_loc="SE";
}
}
}
};

When I hint _N and _E, I get values. However, when I hint _loc, I get the good old scalar error message. Why isn't it working? I couldn't find an example of an if based on two conditions.

Oh, and I haven't yet checked what I'll have to do with te script to get it to work in MP.


Edit, I solved this. I hadn't initialised the variable, and it wasn't therefore available out of scope. :whistle:
« Last Edit: 22 Feb 2008, 21:41:17 by CharlieReddog »

Offline Spooner

  • Members
  • *
  • Mostly useless
    • Community Base Addons
Re: MP Briefings
« Reply #6 on: 23 Feb 2008, 13:00:12 »
The problem is that _loc is a local variable, only defined inside the if/then blocks since that is the only place that it is mentioned. Thus, at the end of the script when you are attempting to use it, it is undefined. What you need to do is to define it at the top of the script with private, so that it will exist throughout the script:
Code: [Select]
private "_loc";

Not sure whether that is what you meant that you'd used private or just initialised the value in your post edit. In this sort of situation, I prefer to just define it, rather than define and initialise it, since any value you give to it would be arbitrary. As usual, though, if it works, don't try to fix it, eh?

Also, you might find my function SPON_directionName useful for doing what you are doing, though if you have coded it satisfactorily now, it might be a little late to tell you that as well ;P.
[Arma 2] CBA: Community Base Addons
[Arma 1] SPON Core (including links to my other scripts)

Offline CharlieReddog

  • Members
  • *
Re: MP Briefings
« Reply #7 on: 24 Mar 2008, 10:45:01 »
Hi.

I'm still having problems with the briefings for clients. I believe that this is solveable, but I cannot get my head round it now.

The current code has the following
Code: [Select]
_intRndLoc=random 12.9;
_intRndWth=random 6;
_intRndLoc =1 + (floor _intRndLoc) ;
if (!isServer) exitWith {};

_intrndType=random 4.9;
//_intrndType= 4.9;
_strLocX= call compile format["getpos lgc_%1 select 0",_intrndloc];
_strLocY= call compile format["getpos lgc_%1 select 1",_intrndloc];

//Now we get rid of decimals, the result is a random beteen 0 and 10 plus 1 (1 -> 11)
//_intRndtype2 = 1 + _intRndtype - (_intRndtype mod 1);
_intrndtype2=floor _intrndtype;

_N=random 1;
_E=random 1;

if (_N>=0.5) then {_N=1} else {_N=0};
if (_E>=0.5) then {_E=1} else {_E=0};
_loc="";
if (_N==0 and _E==0) then {
_loc= "NE";
}
else
{
if (_N==1 and _E==1)then {
_loc= "SW";
}
else
{
if (_N==0 and _E==1)then {
_loc= "NW";
}
else
{
if (_N==1 and _E==0)then {
_loc="SE";
}
}
}
};

switch (_intrndType2) do
{
    case 0:
    {
"mkr_Patrol" setmarkerpos [_strLocX,_strLocY,0];
"mkr_Assass" setmarkertype "empty";
"mkr_destroy" setmarkertype "empty";
"mkr_Rescue" setmarkertype "empty";
"mkr_AA" setmarkertype "empty";
"2" objstatus "Hidden";
"3" objstatus "Hidden";
"4" objstatus "Hidden";
"5" objstatus "Hidden";
trgZone1 setpos [_strLocX,_strLocY,0];

    };

I believe the answer lies in the fact that the objectives are only being hidden on the server, and not on the clients because of the
Code: [Select]
if (!isServer) exitWith {}; line. I guess I need to maybe run the objstatus lines on the client, but how to exit the code at the appropriate place without spawning different locations for every client?

Offline Spooner

  • Members
  • *
  • Mostly useless
    • Community Base Addons
Re: MP Briefings
« Reply #8 on: 25 Mar 2008, 18:09:45 »
All you need to do is put the objective-hiding code before "if (isServer) exitWith {}" to make it run on all machines, including clients. Or is it the case that different objectives are enabled or disabled randomly? If this is the case, you need to work out which objectives should be enabled or disabled on the server and communicate this choice to the clients (See the ArmA MP tutorial for some ways you could do this).

The marker-code does need to only be run on the server since the marker locations are random and if you worked out random numbers in scripts on every machine, then every machine would have different locations. This is fine though, since markers are global, unless they are specifically created as local markers, so they will automatically be syncronised from the server to the clients.
[Arma 2] CBA: Community Base Addons
[Arma 1] SPON Core (including links to my other scripts)

Offline CharlieReddog

  • Members
  • *
Re: MP Briefings
« Reply #9 on: 25 Mar 2008, 19:30:14 »
Spooner,

Thanks for the help. I actually thnk I've solved my problem, by making the mission type a public variable, and then running another script which uses the public variable to determine whch objectives to hide. As you surmised, the objectives are random as well as the locations, which I hope will lead to a dynamic "one size fits many" mission which is both MP and SP compatible.

I've looked at the MP tutorial, and have it bookmarked. I have a real problem with locality etc, for which the tute explaining how to set up a server is very handy. Might I suggest that the tutorial make reference to -mod parameters as well for the server, as that hung me up for a while. ???

For completeness should anyone be using this code as a basis for anything else, here's my hopefully working version.
Code: [Select]
_intRndLoc=random 12.9;
_intRndWth=random 6;
_intRndLoc =1 + (floor _intRndLoc) ;
_intrndType=random 4.9;
//_intrndType= 4.9;
_strLocX= call compile format["getpos lgc_%1 select 0",_intrndloc];
_strLocY= call compile format["getpos lgc_%1 select 1",_intrndloc];

//Now we get rid of decimals, the result is a random beteen 0 and 10 plus 1 (1 -> 11)
//_intRndtype2 = 1 + _intRndtype - (_intRndtype mod 1);
_intrndtype2=floor _intrndtype;
intType=_intrndtype2;
publicvariable "intType";
call compile preprocessFileLineNumbers "Briefings.sqf";
if (!isServer) exitWith {};

Briefings.sqf
Code: [Select]
switch (intType) do
{
    case 0:
    {
"2" objstatus "Hidden";
"3" objstatus "Hidden";
"4" objstatus "Hidden";
"5" objstatus "Hidden";
    };
    case 1:
    {
"1" objstatus "Hidden";
"3" objstatus "Hidden";
"4" objstatus "Hidden";
"5" objstatus "Hidden";
};
    case 2:
    {
"1" objstatus "Hidden";
"2" objstatus "Hidden";
"4" objstatus "Hidden";
"5" objstatus "Hidden";
    };
    case 3:
    {
"1" objstatus "Hidden";
"3" objstatus "Hidden";
"2" objstatus "Hidden";
"5" objstatus "Hidden";
    };
    case 4:
    {
"1" objstatus "Hidden";
"3" objstatus "Hidden";
"2" objstatus "Hidden";
"4" objstatus "Hidden";
    }; 
};

I'm still concerned that there may be a problem, but I'm guessing that if a piece of code is run on server and clients, and then a publicvariable is created, it will be the server's version which is used and transmitted?


EDIT: No, it doesn't work! ARGH! >:(
« Last Edit: 25 Mar 2008, 20:52:49 by CharlieReddog »

Offline Spooner

  • Members
  • *
  • Mostly useless
    • Community Base Addons
Re: MP Briefings
« Reply #10 on: 25 Mar 2008, 21:34:13 »
You have a couple of issues here. You are setting and publicing the value on all machines, not just the server, so it is anyone's guess which value will be the last one sent! What you should do is work out and public the value only on the server. Perhaps you intended to put the "if (isServer) exitWith {}" earlier in the script to prevent code after it from being run on the clients?

However, even should you only send from the server, you only have one value flying around, but then the issue would be that the server might well transmit the "intType" after the clients are check its value. This would also happen when you JIP, since I think it takes a while for the public data to be fully synchronised, but the init.sqf will be run right away. Anyway, if the "switch (intType)" is run before the data has been syncronised between machines, intType will be undefined (nil) and none of the switch cases will ever be run!

Code: [Select]
// Run code on any server (dedicated or host) to choose a mission type.
if (isServer) then
{
    // "random 5" gives a number from 0 up to, but not including, 5 (so 0 to, approximately, 4.99999999).
    intType = floor (random 5);
    publicvariable "intType";
};

// Run code on any client (dedicated, MP host or SP)
if ((not isServer) or (not (isNull player))) then
{
    // Spawn, rather than call, the file since it will take an indeterminate amount of time to finish and we don't want to wait for it
    // execVM would also work.
    spawn compile preprocessFileLineNumbers "Briefings.sqf";
};

Code: (briefing.sqf) [Select]
// Initially, hide all objectives, to prevent confusion.
"1" objstatus "Hidden";
"2" objstatus "Hidden";
"3" objstatus "Hidden";
"4" objstatus "Hidden";
"5" objstatus "Hidden";

// Wait until we have received the publicVariabled value (either when it is sent or else when we JIP)
waitUntil { not (isNil "intType") };

// Show the objective which is actually active.
switch (intType) do
{
    case 0:
    {
        "1" objStatus "Active";
    };
    case 1:
    {
        "2" objStatus "Active";
    };
    ...etc...
};

[Arma 2] CBA: Community Base Addons
[Arma 1] SPON Core (including links to my other scripts)

Offline CharlieReddog

  • Members
  • *
Re: MP Briefings
« Reply #11 on: 25 Mar 2008, 22:03:19 »
Thanks for the help. I've copied it in, and swapped bits around. I got a "string error" on line 16 so changed to this
Code: [Select]
if ((!isServer) or (!isNull player)) then and no error. I only got one briefing (preview in editor) but I got all 5 markers so clearly the briefings.sqf fired but the code following doesn't work now.

Why do I get myself into these pickles? ???


Here's the entire start.sqf just to be certain I'm not screwing up something.

Code: [Select]
_intRndLoc=random 12.9;
_intRndWth=random 6;
_intRndLoc =1 + (floor _intRndLoc) ;


if (isServer) then
{
    // "random 5" gives a number from 0 up to, but not including, 5 (so 0 to, approximately, 4.99999999).
    intType = floor (random 5);
    publicvariable "intType";

};

if ((!isServer) or (!isNull player)) then
{
    // Spawn, rather than call, the file since it will take an indeterminate amount of time to finish and we don't want to wait for it
    // execVM would also work.
    spawn compile preprocessFileLineNumbers "Briefings.sqf";
};

    _strLocX= call compile format["getpos lgc_%1 select 0",_intrndloc];
_strLocY= call compile format["getpos lgc_%1 select 1",_intrndloc];


if (!isServer) exitWith {};
_N=random 1;
_E=random 1;

if (_N>=0.5) then {_N=1} else {_N=0};
if (_E>=0.5) then {_E=1} else {_E=0};
_loc="";
if (_N==0 and _E==0) then {
_loc= "NE";
}
else
{
if (_N==1 and _E==1)then {
_loc= "SW";
}
else
{
if (_N==0 and _E==1)then {
_loc= "NW";
}
else
{
if (_N==1 and _E==0)then {
_loc="SE";
}
}
}
};

switch (_intrndType2) do
{
    case 0:
    {
"mkr_Patrol" setmarkerpos [_strLocX,_strLocY,0];
"mkr_Assass" setmarkertype "empty";
"mkr_destroy" setmarkertype "empty";
"mkr_Rescue" setmarkertype "empty";
"mkr_AA" setmarkertype "empty";
trgZone1 setpos [_strLocX,_strLocY,0];
trgZone3 setpos [_strLocX,_strLocY,0];

    };

    case 1:
    {
"mkr_Destroy" setmarkerpos [_strLocX,_strLocY,0];
"mkr_Assass" setmarkertype "empty";
"mkr_patrol" setmarkertype "empty";
"mkr_Rescue" setmarkertype "empty";
"mkr_AA" setmarkertype "empty";
trgZone1 setpos [_strLocX,_strLocY,0];
trgZone3 setpos [_strLocX,_strLocY,0];
switch (_loc) do
{
case "NE":
{
AM1 setpos [_strLocX+200+random 200,_strLocY+200+random 200,0];
Net1 setpos getpos AM1;
};
case "NW":
{
AM1 setpos [_strLocX+200+random 200,_strLocY-200-random 200,0];
Net1 setpos getpos AM1;
};
case "SW":
{
AM1 setpos [_strLocX-200-random 200,_strLocY-200-random 200,0];
Net1 setpos getpos AM1;
};
Case "SE":
{
AM1 setpos [_strLocX-200-random 200,_strLocY+200+random 200,0];
Net1 setpos getpos AM1;
};
};
};

   
    case 2:
    {
"mkr_AA" setmarkerpos [_strLocX,_strLocY,0];
"mkr_Assass" setmarkertype "empty";
"mkr_patrol" setmarkertype "empty";
"mkr_destroy" setmarkertype "empty";
"mkr_Rescue" setmarkertype "empty";
AAMission=true;
publicVariable "AAMission";
trgZone1 setpos [_strLocX,_strLocY,0];
trgZone2 setpos [_strLocX,_strLocY,0];
execvm "shilkatest.sqf";
trgZone3 setpos [_strLocX,_strLocY,0];
    };
   
    case 3:
    {
"mkr_Rescue" setmarkerpos [_strLocX,_strLocY,0];
"mkr_Assass" setmarkertype "empty";
"mkr_patrol" setmarkertype "empty";
"mkr_AA" setmarkertype "empty";
"mkr_destroy" setmarkertype "empty";
trgZone1 setpos [_strLocX,_strLocY,0];
[ChopWreck] exec "smokescript2.sqs";
[trig1,grpCrew] exec "triggertrack.sqs";
trgZone3 setpos [_strLocX,_strLocY,0];
switch (_loc) do
{
case "NE":
{
ChopWreck setpos [_strLocX+400+random 200,_strLocY+400+random 200,0];
};
case "NW":
{
ChopWreck setpos [_strLocX+400+random 200,_strLocY-400-random 200,0];
};
case "SW":
{
ChopWreck setpos [_strLocX-400-random 200,_strLocY-400-random 200,0];
};
Case "SE":
{
ChopWreck setpos [_strLocX-400-random 200,_strLocY+400+random 200,0];
};

};
_x=getpos ChopWreck select 0;
_y=getpos ChopWreck select 1;
Crew1 setpos [_x+2,_y+2,0];
crew2 setpos getpos crew1;
crew3 setpos getpos crew1;   
    };
   
        case 4:
    {
"mkr_Assass" setmarkerpos [_strLocX,_strLocY,0];
"mkr_Destroy" setmarkertype "empty";
"mkr_rescue" setmarkertype "empty";
"mkr_AA" setmarkertype "empty";
"mkr_Patrol" setmarkertype "empty";
trgZone1 setpos [_strLocX,_strLocY,0];
trgZone3 setpos [_strLocX,_strLocY,0];
eUAZ setpos getmarkerpos "mkr_assass";
AssMission=true;
publicVariable "AssMission";
    };
   
   
};

MissionStarted=true;
publicvariable "MissionStarted";
« Last Edit: 25 Mar 2008, 22:10:32 by CharlieReddog »

Offline Spooner

  • Members
  • *
  • Mostly useless
    • Community Base Addons
Re: MP Briefings
« Reply #12 on: 25 Mar 2008, 23:59:20 »
I removed the unnecessary _intrndType2 value, since it is just the same as intType. You continue to use _intrndType2 in the switch further along, which might as well just be "switch (intType) {". Since this variable is undefined, the whole switch, and all of its cases, will be ignored.

Incidentally, you publicVariable a few values which seem unnecessary, specifically AAMission and AssMission, (since the information could be worked out simply by looking at the value of intType) and dangerously likely to causes errors (since they aren't initialised and publiced if they aren't "true", so it is impossible to tell, from other machines, whether the value hasn't been syncronised yet or whether it just hasn't been set). Hope that makes sense...
[Arma 2] CBA: Community Base Addons
[Arma 1] SPON Core (including links to my other scripts)

Offline CharlieReddog

  • Members
  • *
Re: MP Briefings
« Reply #13 on: 26 Mar 2008, 00:08:33 »
I removed the unnecessary _intrndType2 value, since it is just the same as intType. You continue to use _intrndType2 in the switch further along, which might as well just be "switch (intType) {". Since this variable is undefined, the whole switch, and all of its cases, will be ignored.

D'Oh. :clap:


Incidentally, you publicVariable a few values which seem unnecessary, specifically AAMission and AssMission, (since the information could be worked out simply by looking at the value of intType) and dangerously likely to causes errors (since they aren't initialised and publiced if they aren't "true", so it is impossible to tell, from other machines, whether the value hasn't been syncronised yet or whether it just hasn't been set). Hope that makes sense...

Those publicVariables are initialised in the init.sqf. I agree, we can probably get rid of them now that intType is being used.

Not entirely sure what you mean but the syncronised bit etc though, because it comes after the exit if not server, so it should only be the server which sets that value no??

Thanks ever so much for your help with this.

Offline Spooner

  • Members
  • *
  • Mostly useless
    • Community Base Addons
Re: MP Briefings
« Reply #14 on: 26 Mar 2008, 00:27:55 »
OK, if one of those variables is publiced, then it will be true after that point on all machines. Now, on my client I want to see if AAMission has been set. How can I tell the difference between these two cases:
* We are doing the AA mission. AAMission has been set to true on the server and publicVariabled, but the value hasn't been set on my client yet. The value is therefore undefined (nil), but at some time in the future it will be true.
* We are doing one of the other missions. AAMission will never get set on the AAMission and never be publicVariabled. The value is undefined (nil) and will always be undefined.

You see the problem? If you wait for the value to be set, it might never get set. If you assume that undefined means that you aren't doing the AA mission, then the value might get set later on! In this case you can just look at intType to work out the values, which is always sent and thus you know that all you have to do is wait for it to be set and look at the value. If you need to send values like this, however, all you need to do is make sure that you send the value whether it is true or false. You can't assume that "undefined" is false when you are transmitting variables, as you are doing.
[Arma 2] CBA: Community Base Addons
[Arma 1] SPON Core (including links to my other scripts)