Home   Help Search Login Register  

Author Topic: Firing Range Hint Problem  (Read 4375 times)

0 Members and 1 Guest are viewing this topic.

Offline Ironman

  • Former Staff
  • ****
    • {GSF} Home Page
Firing Range Hint Problem
« on: 07 Mar 2010, 01:28:45 »
So, I want a hint to display when a target is hit. But I only want the hint to show for the player that actually is on the Firing Range, "client", not the whole server. Now, I tried running this script in a addAction but that didn't work at all, probably because of the  "if (isServer)" condition. So I put it in a radio command and now all the targets pop up fine. However, I know there is a way to return the player's name that initiates a addAction and I don't think there is anyway to return a name with radio commands, plus the person that activates the radio command to run the script isn't the one on the Firing Range. So, I would like it if addAction could work and if someone could give me the code for the hint which would only show on the person activating the action.

Code: [Select]
//place this line in a trigger: _iron=[] execVM "popup.sqf"

_inc     = 0;
_count   = 0;
_targets = [t50,t75,t100,t125,t150,t200];
_many    =  count _targets-1;

if (isserver) then
{
   nopop=true;
   {_x  animate["terc",1]} forEach _targets;

   sleep 5;

   while {_inc<40} do
   {
     _rnumber = random _many;
     _rtarget = _targets select _rnumber;
     _rtarget animate["terc", 0];
     sleep 3;
     if (_rtarget animationPhase "terc" > 0.1) then
     {
_count = _count+1;
     };
//* this is the code that needs to be placed outside of the loop and referenced somehow hintSilent format ["hits %1.", _count];
*//
     _rtarget animate["terc", 1];
     sleep 1;
     _inc = _inc + 1;

     if ( _inc == 40) then
     {
_command = format ["remotecommand=this; di_1 globalchat ""  %1 out of : %2 "";",_count,_inc];
// Old ofp style hack
"RU_Citizen1" createUnit [[0,0,0], createGroup west, _command, 0, "PRIVATE"];
sleep(0.5);
deletevehicle remotecommand;
     }
   };//end of while loop
};//end of if-then statement
« Last Edit: 07 Mar 2010, 19:54:33 by Ironman »
TS3 IP: tor.zebgames.com:9992

Offline Ironman

  • Former Staff
  • ****
    • {GSF} Home Page
Re: Firing Range Hint Problem
« Reply #1 on: 10 Mar 2010, 01:41:29 »
did I do a bad job of explaining the problem? No feedback at all?
TS3 IP: tor.zebgames.com:9992

Offline Loyalguard

  • Former Staff
  • ****
Re: Firing Range Hint Problem
« Reply #2 on: 10 Mar 2010, 15:37:32 »
I am working on a solution probably using publicvariable but I need a little more time.

To make sure I understand correctly, there are two units involved: the "instructor" who initiates the target sequence and the "shooter" who is on the range and needs to see the hint. Is that correct?  I'll proceed as if it is in the meantime.

Edited to add the below:

Ok, this is untested, but assuming my assumption above is correct,

Here's the plan:

I recommend leaving the method of execution of popup.sqf as a radio trigger (at least for now) because it has the benefit of being executed globally.

First thing to do is to place a trigger in the editor that will detect when a player is on the range and report who that player is.  Make sure the detection area covers the whole range or maybe more appropriately the firing line.  Make sure it is activated by anyone and it is set to repeatedly.  In the condition field enter the following:

Code: [Select]
player in thisList
This means the trigger should only fire locally (since the player is only local to his machine).

For the activation field enter the following:

Code: [Select]
pvShooter=player; publicVariable "pvShooter";
And the below for deactivation:

Code: [Select]
pvShooter=nil; publicVariable "pvShooter";
What this does is create a variable with the player's unit and when the trigger fires it publicly broadcasts who the shooter is so we can later determine who sees the hint.  On deactivation it removes the player from seeing the hint.

Next add this to your init.sqf:

Code: [Select]
pvHits=0; // Create a global variable that will later be broadcast publicly.
publicVariable "pvHits"; // Publicly broadcast pvHits to all machines.
"pvHits" addPublicEventHandler {if (pvSHooter==player && _pvHits!=0) then {hintSilent format ["hits %1.", _pvHits]};}; // Display a hint only to the player on the range (pvShooter) and only if there has been at least one hit.

Basically, a new publc variable called pvHits will replace your _count variable in popup.sqf.  We add the pv event handler that when pvHits changes will broadcast the new value to every other machine except the one where it intially changed.  When it does fire, if the player is the player on the range (pvShooter) the hint will be displayed.  If not, nothing.

Finally, here are the changes to popup.sqf:

Code: [Select]
//place this line in a trigger: _iron=[] execVM "popup.sqf"

_inc     = 0;
//_count   = 0; //Remove this code as it has now been replaced with a public variable pvHits.
_targets = [t50,t75,t100,t125,t150,t200];
_many    =  count _targets-1;

if (isserver) then
{
   nopop=true;
   {_x  animate["terc",1]} forEach _targets;

   sleep 5;

   while {_inc<40} do
   {
     _rnumber = random _many;
     _rtarget = _targets select _rnumber;
     _rtarget animate["terc", 0];
     sleep 3;

     if (_rtarget animationPhase "terc" > 0.1) then
     {
pvHits=pvHits+1; // Increase the hit count by 1.
publicVariable "pvHits"; // Publicly broadcast the new value so that the EH fires to give a hint to the shooter.
     };

     _rtarget animate["terc", 1];
     sleep 1;
     _inc = _inc + 1;

     if ( _inc == 40) then
     {
_command = format ["remotecommand=this; di_1 globalchat ""  %1 out of : %2 "";",pvHits,_inc]; // changed _counts to pvHits.
pvHits=0; // Reset the number of hits to zero.
// Old ofp style hack
"RU_Citizen1" createUnit [[0,0,0], createGroup west, _command, 0, "PRIVATE"];
sleep(0.5);
deletevehicle remotecommand;
     }
   };//end of while loop
};//end of if-then statement

Give that a shot and see how it goes.  If you want to attach your mission as a .zip or .rar I would be happy to test it out to see if there any bugs.  I'm sure there are other ways of doing this (and probably better ways) but I figured we should get something working and see if we can improve upon it later. Good luck!!!
« Last Edit: 11 Mar 2010, 05:13:26 by Loyalguard »

Offline Ironman

  • Former Staff
  • ****
    • {GSF} Home Page
Re: Firing Range Hint Problem
« Reply #3 on: 11 Mar 2010, 05:22:18 »
the way it is now:

There are 3 AI near each firing range, their names are di_1, di_2, di_3. I tried using them for the addAction to initiate this script. This current script initiates with a radio trigger that a human player can trigger off. If I can make the scipt compatable for an addAction I could return this information:

Params passed by an action to the executed script:
[(object action was attached to), (unit that activated action), (index of action)]

Using that I think it would be possible for only the player initiating the addAction to see the hint that a target is down.

Hope I made myself clear.
TS3 IP: tor.zebgames.com:9992

Offline Loyalguard

  • Former Staff
  • ****
Re: Firing Range Hint Problem
« Reply #4 on: 11 Mar 2010, 05:34:40 »
Ah, so what you want is the addAction attached to the AIs so a human walks up to them to activate the script, right?

Ok, let me re-work it. I will cook it up tonight and test on a ded server and have something for you in the morning!

Edit Thurs AM:

Still having some probs...will report in soon!

Edit Thurs PM:

Sorry, but I have been problems getting it to work MP, I am still rusty after being gone a few years.  I don't think I will have time to work on it in the short term.  I am trying to get the AddAction to trigger a script on the server to run popup and then report the hits to the player only using public variables and pv event handlers but I am missing something somewhere.  Sorry!!!!!!!!!!!!!!!!!!!!!!!!!!!
« Last Edit: 11 Mar 2010, 19:03:48 by Loyalguard »

Offline Ironman

  • Former Staff
  • ****
    • {GSF} Home Page
Re: Firing Range Hint Problem
« Reply #5 on: 12 Mar 2010, 02:32:01 »
hopefully someone else can chime in to help us with the locality. Once that is figured out I think displaying the hint would be quite easy.
TS3 IP: tor.zebgames.com:9992

Offline Loyalguard

  • Former Staff
  • ****
Re: Firing Range Hint Problem
« Reply #6 on: 20 Mar 2010, 08:55:32 »
I had some time to work on this again tonight and I think we got it.  Here is the basic scheme.

When the player activates the addAction to start the range session, the script only executes locally on the player's client.  But, we need the popup script to only run on the server in order to make sure the animations work correctly.  So, the addAction executes a script called startRange.sqf.  This script doesn't actually start the popup script, but it alerts the server to start it with a public variable event handler.  When a public variable (IRON_rangeStarted) is set to true and is broadcasted from the player's client to all other clients and the server the PVEH fires the popupscript.   startRange.sqf also records the name of the player that activated the addAction for later use to make sure only that player sees the hint.  So, the PVEH fires and only the server runs popup.sqf (via isServer).  This script does whatever you want it to do (i.e. animate the popups, records hits, etc) and records the number of hits in another public variable called IRON_count.  Now since IRON_count only changes on the server (where popup.sqf is run) we broadcast it to all other clients (to include the player who activated the addAction) which in turn fires another PVEH that whenever the hit count changes, it will show a hint with the number of hits only to the player who activated the addAction.  I have tested this on a dedicated server with two clients connected and verified you only see a hint on whatever client activates the addAction. Here is all the code you need:

Editor: Put this in unit di_1's (or any unit's) init line:

Code: [Select]
actionId = this addAction ["Start Range", "startRange.sqf", [], 1, true, true, "", ""];This is the addAction that starts the range as you described you wanted (I think).

Next, init.sqf:

Code: [Select]
// init.sqf

// Initilaize a global variable that will record who started a new range session.  It will be given a real value and broadcasted publicly in startRange.sqf.
IRON_caller = objNull;

// Create a global variable that will determine when a new range session has started.
IRON_rangeStarted = false;

// Add a PVEH so if a new range session has started then execute popup.sqf.
"IRON_rangeStarted" addPublicVariableEventHandler {if (IRON_rangeStarted) then {_iron=[] execVM "popup.sqf"}};

// Create a global variable that will record the number of hits on target.  The server and clients will start with 0.
IRON_count = 0;

// Add a PVEH to show the hint only to the player when the hit count changes.
"IRON_count" addPublicVariableEventHandler {if (player == IRON_caller) then {hintSilent format ["hits %1.", IRON_count]}};;

startRange.sqf:
Code: [Select]
// startRange.sqf

// parameters passed from the addAction "Start Range" in  the unit's editor init line (not all variables are used).

_target = _this select 0;
_caller = _this select 1;
_id = _this select 2;
_arguments = _this select 3;

// Record who initiated the new range session and  broadcast it to the server and all clients.
IRON_caller = _caller;
publicVariable "IRON_caller";

// Indicate that a new range session has started and broadcast it to the server and all clients so a PVEH will start the popup script.
IRON_rangeStarted = true;
publicVariable "IRON_rangeStarted";

popup.sqf

*NOTE: I did not use the code in your script because without your mission and the range, targets, etc. set up properly I can't really test it...so, I used code that simulated a range session by increasing the hit count.  Here it is:

Code: [Select]
//popup.sqf

// Only run this script on the server.

if (isServer) then
{
// Simulate targets popping up, and one gets hit.
IRON_count = 0; //Reset the hit count to 0.
IRON_count = IRON_Count+1; // Increase the hit count so we can see a result.

//After each round re-broadcast IRON_count so that tehe PVEH will fire and show a hint to the player on the range.
publicVariable "IRON_count"; // Broadcast the hit count and trigger a hint to the player.

// When the session is over reset the range.
IRON_rangeStarted = false; // Reset the range PV so if a new session is started the PVEH will fire again.
publicVariable "IRON_rangeStarted"; // Broadcast that the range is over.
};

I wanted you to see this so you could trace the methodology,this is untested, but I think your actual script should look like this I think:

Code: [Select]
_inc     = 0;
_count   = 0;
_targets = [t50,t75,t100,t125,t150,t200];
_many    =  count _targets-1;

if (isserver) then
{
   nopop=true;
   {_x  animate["terc",1]} forEach _targets;

   sleep 5;

   while {_inc<40} do
   {
     _rnumber = random _many;
     _rtarget = _targets select _rnumber;
     _rtarget animate["terc", 0];
     sleep 3;
     if (_rtarget animationPhase "terc" > 0.1) then
     {
IRON_count = _count+1; // Changed to make use of the PVEH
     };

publicVariable "IRON_count"; // Broadcast the new hit count and trigger a hint to the player.

     _rtarget animate["terc", 1];
     sleep 1;
     _inc = _inc + 1;

     if ( _inc == 40) then
     {
_command = format ["remotecommand=this; di_1 globalchat ""  %1 out of : %2 "";",_count,_inc];
// Old ofp style hack
"RU_Citizen1" createUnit [[0,0,0], createGroup west, _command, 0, "PRIVATE"];
sleep(0.5);
deletevehicle remotecommand;

// When the session is over reset the range.
IRON_rangeStarted = false; // Reset the range PV so if a new session is started the PVEH will fire again.
publicVariable "IRON_rangeStarted"; // Broadcast that the range is over.

     }
   };//end of while loop
};//end of if-then statement

I am attaching the test mission I used to test it, just unzip it, open in the editor, and export it to your MP missions folder to test on a ded server (it will not work properly in the editor because of isServer and the PVEHs).  There are two playable positions so you can see one get the hint and one doesn't.  I hope this helps and good luck!

-Loyal


« Last Edit: 21 Mar 2010, 06:28:24 by Loyalguard »

Offline Ironman

  • Former Staff
  • ****
    • {GSF} Home Page
Re: Firing Range Hint Problem
« Reply #7 on: 21 Mar 2010, 05:42:12 »
Wow, that is freakin ridiculous lol.... just for a simple hint msg.

Thanks for the hard work. I didn't upload my mission because it has a lot of addons in it which you probably wouldn't appreciate DL them all just to look at the script.

Question: Should I just turn the "_count" variable into "_Iron_count"?

I am sure I will have more questions once I try to implement it. But thanks for your work, many kudos...

Probably test it out on Monday.
TS3 IP: tor.zebgames.com:9992

Offline Loyalguard

  • Former Staff
  • ****
Re: Firing Range Hint Problem
« Reply #8 on: 21 Mar 2010, 06:36:25 »
Quote
Wow, that is freakin ridiculous lol.... just for a simple hint msg.
Ah, the joys of MP scripting!!!!  There may be a simpler way but this is what first occurred to me.

regarding _count...I left it as _count in order to change as little in your original script as possible.  You can easily change it for IRON_count throughout if you think that is simpler...either way it doesn't get broadcasted until its ready for the hint.

BTW, I just realized I typed _IRON_count...it should only be IRON_count...drop the preceding underscore or it will screw it all up...sorry...I fixed it in the code above so it's correct now.

Offline Ironman

  • Former Staff
  • ****
    • {GSF} Home Page
Re: Firing Range Hint Problem
« Reply #9 on: 02 May 2010, 23:41:11 »
ok so update... I think the _count is useless now....

Anything with the _count should be switched to IRON_count. Otherwise the script will only count the first target hit in the hint but _count will be never set to any value. Am I right?
TS3 IP: tor.zebgames.com:9992

Offline Loyalguard

  • Former Staff
  • ****
Re: Firing Range Hint Problem
« Reply #10 on: 03 May 2010, 05:06:49 »
Yeah, just go with te IRON_ version to safe.

Offline Ironman

  • Former Staff
  • ****
    • {GSF} Home Page
Re: Firing Range Hint Problem
« Reply #11 on: 03 May 2010, 08:12:29 »
On another note... This works great with one lane. What would need to change to get it to work on three seperate lanes?
TS3 IP: tor.zebgames.com:9992

Offline Loyalguard

  • Former Staff
  • ****
Re: Firing Range Hint Problem
« Reply #12 on: 03 May 2010, 20:55:35 »
To get it to work on three different lanes there are two different methods that immediately come to mind:

1.  Create three different versions of each component (i.e. PV, PVEH, script, etc.), one for each lane.

or

2. Have one version but modify it to start a new instance of that component for each lane via dynamic code or array-driven data, or function driven.

I'll briefly explain.

So, for the first version what you would do for example in init.sqf is:

(again, none of this code has been checked for syntax errors or otherwise tested.)

Code: [Select]
// init.sqf

// Initalize global variables that will record who started a new range session on each lane.  It will be given a real value and broadcasted publicly in startRange_X.sqf.

IRON_caller_1 = objNull;

IRON_caller_2 = objNull;

IRON_caller_3 = objNull;

// Create global variables that will determine when a new range session has started on each lane.

IRON_rangeStarted_1 = false;

IRON_rangeStarted_2 = false;

IRON_rangeStarted_3 = false;

// Add PVEHs so if a new range session has started then execute popup_X.sqf.

"IRON_rangeStarted_1" addPublicVariableEventHandler {if (IRON_rangeStarted_1) then {_iron=[] execVM "popup_1.sqf"}};

"IRON_rangeStarted_2" addPublicVariableEventHandler {if (IRON_rangeStarted_2) then {_iron=[] execVM "popup_2.sqf"}};

"IRON_rangeStarted_3" addPublicVariableEventHandler {if (IRON_rangeStarted_3) then {_iron=[] execVM "popup_3.sqf"}};

// Create global variables that will record the number of hits on target on each lane.  The server and clients will start with 0.

IRON_count_1 = 0;

IRON_count_2 = 0;

IRON_count_3 = 0;

// Add PVEHs to show the hint only to the player when the hit count changes.

"IRON_count_1" addPublicVariableEventHandler {if (player == IRON_caller_1) then {hintSilent format ["hits %1.", IRON_count_1]};};

"IRON_count_2" addPublicVariableEventHandler {if (player == IRON_caller_2) then {hintSilent format ["hits %1.", IRON_count_2]};};

"IRON_count_3" addPublicVariableEventHandler {if (player == IRON_caller_3) then {hintSilent format ["hits %1.", IRON_count_3]};};

So, you can see where this one is going.  You have to create three different versions of each GV/PV and PVEH and then create three different versions of each script for each lane.  I used the suffix _1, _2, _3 to demonstrate this, but you could use any format you want.  The advantage to this version is that it is a simple implementation and easy to debug (aside from all of the copying/pasting or manual entry of all of the variations). The disadvantage is, well, all of the copying/pasting or manual entry of the variations ;) . So, that takes us to the second method.

In order to avoid re-writing essentially the same code over and over again with slight variations, we could modify the code as it it currently is to 'dynamically' create the PVs / PVEHs using "call compile format", or retriecing the data from a global array, or possibly my functions (I haven't thought out the function methodology for this example so I may have to retreat from it later).  The advantage of this method is that you don't have to create new versions of all of those components, but, it can be harder to debug since 'call compile format" doesn't give you line number references in error messages and there is a lot of room for syntax mistakes.  If you use global arrays you are probably better off with speed and accuracy but there can be other downsides that could take awhile to explain....anyway, here is a brief overview of how this could be done:

Code: [Select]
// init.sqf

_suffixes = [1,2,3]

// Initilaize global variables that will record who started a new range session on each lane.  It will be given a real value and broadcasted publicly in startRange_X.sqf.

{call compile format ["IRON_caller_%1 = objNull;" _x];} forEach _suffixes;

...

// Add a PVEH so if a new range session has started then execute popup.sqf.

{call compile format ['"IRON_rangeStarted_%1" addPublicVariableEventHandler {if (IRON_rangeStarted_%1) then {_iron=[] execVM "popup_%1.sqf"}};', _x];} forEach _suffixes;

....

The above version is truncated, but you can see it means writing a lot less code.  This is only the "call compile format" version AND it doesn't show how it works in the script (you have to pass to the script which version of the PV you are dealing with).

I personally use version 2 when dealing with a lot of repetive code, but I am also willing to pull my hair out while debugging it.  I know Spooner and others aren't big fans of call compile format, and there are ways to avoid it, but there are some tricks to that too.

However, it is not the "cleanest" way, but version 1 is the best way to see a quick implementation (the goal should be to get it to run, right!).  If you want to pursue a version 2 method I am willing to help. but it will be a LOT more involved.

Offline Ironman

  • Former Staff
  • ****
    • {GSF} Home Page
Re: Firing Range Hint Problem
« Reply #13 on: 04 May 2010, 08:50:35 »
I did it the first way but I actually tried to keep it all in the same scripts... that was an epic fail and a retarded move on my part because I know better than that... but it was late... dont be hating lol
TS3 IP: tor.zebgames.com:9992

Offline Loyalguard

  • Former Staff
  • ****
Re: Firing Range Hint Problem
« Reply #14 on: 04 May 2010, 22:39:07 »
It is not impossible to do it all in one script, you could do that with a switch-do block with cases passed to it from the executing action/script...it would take some more setting up though.  Let me know if you have any probs and we should be able to work them out.

Offline Ironman

  • Former Staff
  • ****
    • {GSF} Home Page
Re: Firing Range Hint Problem
« Reply #15 on: 05 May 2010, 09:00:56 »
I know right, you and I have no lives..... we can figure out anything... can you be my personal scripter lol.... That would be my best dream come true lmao.... but really, it would be.

Anyways, thanks for your help.... now for something completely silly....

http://www.weebls-stuff.com/songs/Amazing+Horse/
TS3 IP: tor.zebgames.com:9992

Offline Ironman

  • Former Staff
  • ****
    • {GSF} Home Page
Re: Firing Range Hint Problem
« Reply #16 on: 10 May 2010, 01:25:03 »
So, my first firing range seems to work fine but when I try to activate other ranges lanes 2 and 3 get their hints mixed up. Like Lane 2 hints show up on Lane 3 and vise versa. Lane 1 continues to work find lmao. The code does not tell it to do this. So, I am confused as hell.
TS3 IP: tor.zebgames.com:9992

Offline Loyalguard

  • Former Staff
  • ****
Re: Firing Range Hint Problem
« Reply #17 on: 10 May 2010, 04:57:23 »
Hmmm, ther must be a variable name or other criss-cross somewhere.  You probably got sabotaged by the copy & paste gremlin!

Offline Ironman

  • Former Staff
  • ****
    • {GSF} Home Page
Re: Firing Range Hint Problem
« Reply #18 on: 10 May 2010, 11:31:02 »
I've been looking for it and haven't found it yet... I am sure you are right.... that is why I took a day to post the problem.... I just can't see it.... AHHHHHHHHHHH!!!! ITS GOT MY NOSE!!!! lol.. I literally can't see it and I am at the point of just going nuts/frustrated/sobbing/mad/throwing computer against wall... lol I am sure my friends at OFPEC understand this feeling.... and in the back of my mind my lil voice is saying... "missing semi colon".... or some small ass bullshit like that...
TS3 IP: tor.zebgames.com:9992