Jump to content
PSYKO_nz

create a new objective when the player sees an object

Recommended Posts

hi there, 

 

im having a bit of trouble with a new objective trigger, the problem is that the trigger is not firing.....

 

the context?

 

the player (team of players - BLUFOR) has been sent to an area to see what's going on there, as they go through town they will find various things (eg a device hanging from a crane) when they look at the device hanging from the crane they need to be given a new task to destroy it or in the case of some documents steal it or in the case of a group of opfor top kill them. however i just can't get the trigger to work i've tried  opfor detected by blufor or owner detected by blufor, even _kv = (side player) knowsAbout _target; PLAYER knowsAbout EAST; or PLAYER knowsAbout HOOKDEVICE;  none of them work!

 

what am i doing wrong?

 

any tips for how to get this working?

Share this post


Link to post
Share on other sites

Not sure where your local variable:  _target is defined. Same for global one: hookdevice.

Do you script your trigger? edit?

In editor try something like trigger none, none, non repeatable , cond act: player knowsabout myTarget > 0   where myTarget is an edited object or unit's name.

 

 

Share this post


Link to post
Share on other sites

thank you,

 

now it's popping but it's popping immediately, i'm not even inside the trigger yet or looking at "hookdevice", i tried changing the number at the end to see if that helped, all the way up to 3.9  the trigger pops at 4 it doesn't i guess because 4 is the max for that variable, any ideas?

Share this post


Link to post
Share on other sites

Would cursorTarget be of any use to you in this situation?

 

Something scripted to the effect of say...

waitUntil {player cursorTarget == myHangingObject};
newObjective = true;

and then in your trigger set the condition as newObjective and set the trigger activation to pop the new objective?

 

I suppose you could put the cursorTarget command right into the trigger's condition field as well if you want to go even simpler, but I don't know all of the conditions you're try to achieve, if you want a slight delay to the player has to actually look at the object for more than a split second, etc.

Share this post


Link to post
Share on other sites

i tried it through a script like you suggested, had an error about waituntil, not sure if it's supposed to or not, haven't used it before. i just copied it right into an .sqf (spot.sqf) and fired it from the init then looked at the thing, it didn't work, may have been the error, may not have been, i'm a bit thick so it could also be my fault.

 

at any rate, what's the cursorTarget line to just put into the trigger condition? basic is good in this instance, i had hoped the normal detected would work, but it didn't, i also put down opfor units and tried to get blu detects op and nothing, unless i was less than 100 meters from them, normally that would be fine but in this situation it has to be the device they see to get the objective.

 

so you can see the issue here is  what they need to look at, it must be able to be seen from any area with a LOS to it around georgetown, here's the angel range and view i've been using to test

 

69B4FD549961519C4C472A56BD4E0E1CBE93D241

 

the thing they need to look at to pop the trigger and assign the new objective is the device that's hanging from the crane. the name of it is "hookdevice" they need to be able to pop if at any range, so if they stop on a hill before entering town they can pop it or if they are muppets and get all the way into town before they see it. as it is nothing i have tried so far has worked

 

thank you for all your help so far! hopefully we crack it soon :)

 

 

Share this post


Link to post
Share on other sites

This should work (assuming you are on dedicated server - you didn't mention it so I guessed).  If not, then you'll have to juggle the execution round a bit (with remoteExec).

 

Put this in init.sqf

 

if (isDedicated) then {
	"TAG_DETECTED" addPublicVariableEventHandler {
		// only setup the task once
		if (isNil "myTaskID") then {
			// set the task up here
			myTaskID = [
				"taskID",										// params
				true,											// target
				["Get to the choppa","Do it","Do it nowwww"],	// desc
				position HOOKDEVICE,							// dest
				"CREATED",										// state
				0,												// priority
				true,											// showNotification
				true,											// isGlobal
				"help",											// type
				false											// shared
			] call BIS_fnc_setTask;
		}
	}
} else {
	0 spawn {
		waitUntil {time > 0};
		onEachFrame {
			// quit if already detected
			if (not isNil "TAG_DETECTED") exitWith {
				onEachFrame {}
			};
			// check what you are looking at
			private _ins = lineIntersectsSurfaces [
				AGLToASL positionCameraToWorld [0,0,0],
				AGLToASL positionCameraToWorld [0,0,1000],
				player
			];
			// no intersection
			if (count _ins == 0) exitWith {};
			// if detected then tell everyone else to stop looking and tell the server to set up the task
			if (_ins select 0 select 3 isEqualTo HOOKDEVICE) then {
				TAG_DETECTED = true;
				publicVariable "TAG_DETECTED"
			}
		}
	}
};

 

  • Like 1

Share this post


Link to post
Share on other sites

RemoteExec version (should work on local hosted as well as dedicated):

// init.sqf

if (isServer) then {
    fnc_setupTask = {
        // only setup the task once
        if (isNil "myTaskID") then {
            // set the task up here
            myTaskID = [
                "taskID",   // params
                true,   // target
                ["Get to the choppa","Do it","Do it nowwww"],   // desc
                HOOKDEVICE,  // dest
                "CREATED",  // state
                0,  // priority
                true,   // showNotification
                true,   // isGlobal
                "help", // type
                false   // shared
            ] call BIS_fnc_setTask;
        }
    }
};
if (hasInterface) then {
    0 spawn {
        waitUntil {time > 0};
        onEachFrame {
            // quit if already detected
            if (not isNil "TAG_DETECTED") exitWith {
                onEachFrame {}
            };
            // check what you are looking at
            private _ins = lineIntersectsSurfaces [
                AGLToASL positionCameraToWorld [0,0,0],
                AGLToASL positionCameraToWorld [0,0,1000],
                player
            ];
            // no intersection
            if (count _ins == 0) exitWith {};
            // if detected then tell everyone else to stop looking and tell the server to set up the task
            if (_ins select 0 select 3 isEqualTo HOOKDEVICE) then {
                TAG_DETECTED = true;
                publicVariable "TAG_DETECTED";
                TAG_DETECTED remoteExec [
                    "fnc_setupTask",
                    2
                ]
            }
        }
    }
};

 

Share this post


Link to post
Share on other sites

I truly don't understand why you broadcast a code for task as far as a task has its own "target" (here true means global channel (everyone included enemies)). It seems to me that on locality of the BIS_fnc_setTask doesn't matter. If someone could confirm...

Share this post


Link to post
Share on other sites
36 minutes ago, pierremgi said:

I truly don't understand why you broadcast a code for task as far as a task has its own "target" (here true means global channel (everyone included enemies)). It seems to me that on locality of the BIS_fnc_setTask doesn't matter. If someone could confirm...

 

I didn't know what OP wanted so I put a generic task pasted from one of my missions in.  I'm sure he can change it to what he wants.

 

Test mission for anyone interested.  (Hookdevice is the beach hut around the corner).

 

https://drive.google.com/open?id=0B1kzYgzONxC0MGRYMXlfYkxDUlk

 

 

Share this post


Link to post
Share on other sites

@das attorney That's a great bit of commented code to learn from, thanks for posting it.  I'm curious why you use lineIntersectsSurfaces rather than cursorTarget for detecting when player sees object?

Share this post


Link to post
Share on other sites

Thanks mate - Just personal preference really.

 

You can use cursorObject instead of cursorTarget as it works even if your avatar doesn't know about what you're looking at, but if you use lineIntersectsSurfaces, you can also get the intersection point, surface normal and proxy (if you are looking at a proxy).

 

Plus you can detect map objects and things with no class.  Additionally, it returns a null object for terrain, so you know if you're staring at the floor, and [] if there is no intersection (looking in the sky), whereas cursorTarget will give you objNull if you are looking in the sky or ground.  IIRC it also works underwater, and from air to water, which I'm not sure cursorTarget/cursorObject will.

  • Like 2

Share this post


Link to post
Share on other sites

Yes great work. I'll just use some waitUntil smooth loop instead of onEachFrame EH. There is no urgent action. Anyone checked the command checkVisibility ? seems to be realistic...

Share this post


Link to post
Share on other sites
38 minutes ago, pierremgi said:

Yes great work. I'll just use some waitUntil smooth loop instead of onEachFrame EH. There is no urgent action.

 

Result:
0.0063 ms

Cycles:
10000/10000

Code:
_ins = lineIntersectsSurfaces [ 
                AGLToASL positionCameraToWorld [0,0,0], 
                AGLToASL positionCameraToWorld [0,0,1000], 
                player 
            ];

I'd say performance is a non issue with lineIntersectsSurfaces.

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites
11 minutes ago, Grumpy Old Man said:

I'd say performance is a non issue with lineIntersectsSurfaces.

 

Cheers

 

Nice to see someone actually checking things rather than believing in blind assumption.

  • Like 1

Share this post


Link to post
Share on other sites
On 9/1/2017 at 10:32 PM, das attorney said:

RemoteExec version (should work on local hosted as well as dedicated):


// init.sqf

if (isServer) then {
    fnc_setupTask = {
        // only setup the task once
        if (isNil "myTaskID") then {
            // set the task up here
            myTaskID = [
                "taskID",   // params
                true,   // target
                ["Get to the choppa","Do it","Do it nowwww"],   // desc
                HOOKDEVICE,  // dest
                "CREATED",  // state
                0,  // priority
                true,   // showNotification
                true,   // isGlobal
                "help", // type
                false   // shared
            ] call BIS_fnc_setTask;
        }
    }
};
if (hasInterface) then {
    0 spawn {
        waitUntil {time > 0};
        onEachFrame {
            // quit if already detected
            if (not isNil "TAG_DETECTED") exitWith {
                onEachFrame {}
            };
            // check what you are looking at
            private _ins = lineIntersectsSurfaces [
                AGLToASL positionCameraToWorld [0,0,0],
                AGLToASL positionCameraToWorld [0,0,1000],
                player
            ];
            // no intersection
            if (count _ins == 0) exitWith {};
            // if detected then tell everyone else to stop looking and tell the server to set up the task
            if (_ins select 0 select 3 isEqualTo HOOKDEVICE) then {
                TAG_DETECTED = true;
                publicVariable "TAG_DETECTED";
                TAG_DETECTED remoteExec [
                    "fnc_setupTask",
                    2
                ]
            }
        }
    }
};

 

 

 

this worked great, however are we able to set this system up to fire a trigger?

 i probably should have said this earlier, my bad!!!

 

i originally set this all up to be a detected trigger (didn't work, hence this post) when the trigger fired (tested with radio alpha) it ticks off the "find out what is going on" sub task and assigns the "blow up the device" new sub task objective as well as being one part of the 6 part "georgetown" main task
here is the task layout

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

 

George town

             find out what is going on


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

when they spot hookdevice new sub task is created and find out ticks - as follows 

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

 

Georgetown             

             find out what is going on (tick - succeded)

             Blow up the devices

                         Device 1

                         Device 2

                         Device 3

                         Device 4

                         Device 5

 

the device (#) sub tasks are hidden until each one is destroyed then each new task assigned already succeeded

all devices and the find out objective need to tick (trigger) to complete the Georgetown main objective

 

throughout the mission (most nzarma missions) we use what we call can triggers where a script (or trigger) sets damage of a can (can is literally just a soda can hidden way out of the way of the AO ie redgull can)

 

we use it as an easy way as syncing a trigger and/or event to all players

 

so for example from an old mission

to get intel you go and speak to a character then when the add action fires...

null = [] execVM "getintel.sqf";

 

getintell.sqf  looks like

Hint "hi there... we have been expecting you. here is your mission";

sleep 5;

IntelCan setDamage 1;

 

then there is a trigger in game that looks for

 

!alive IntelCan

 

when the can dies (setdamage 1) it fires the trigger off, which fires a new task, script or event

 

it works for us every time and keeps things was less complicated script and trigger wise and in very few minutes you can build some complex and dynamic scripts and triggers and events with a basic system of making sure it happens all at the same time on our server, its simple and simple is good, we have been using this system for over a year and it has never failed

 

LONG STORY SHORT

(that took too long to get too but hopefully now you have some idea of how we build.) 

 

MY QUESTION IS....

can that script you have sent through, which works great (locally, haven't had it on server yet)

be modified to when HOOKDEVICE is detected it simply kills a can?

 

ie.

DEVSPOTCAN setdamage 1;

 

if it could it would solve all my problems in one - and i will be able to use this script many times in the future, with a can kill i can build tasks or events or more scripts arround a system i understand well

 

 

if sorry for my low level of understanding here, i'm not the best at all this but your script with all the descriptions is making it easy for me to learn! i thank you so much for your help!

 

 

 

 

 

 

 

  • Like 1

Share this post


Link to post
Share on other sites

That's cool man, it's no problem.

 

You can add an additional line of code in the server part of the script to kill the can.  (So let's kill that fucking can etc etc)

 

if (isServer) then {
    fnc_setupTask = {
        // only setup the task once
        if (isNil "myTaskID") then {
            // set the task up here
            myTaskID = [
                "taskID",   // params
                true,   // target
                ["Get to the choppa","Do it","Do it nowwww"],   // desc
                HOOKDEVICE,  // dest
                "CREATED",  // state
                0,  // priority
                true,   // showNotification
                true,   // isGlobal
                "help", // type
                false   // shared
            ] call BIS_fnc_setTask;
            // now let's kill that fucking can
            DEVSPOTCAN setdamage 1;
        }
    }
};

 

 

No problem about asking questions dude :)

Share this post


Link to post
Share on other sites

 

You sir are a champion!!

 

everything is working both in the editor and on the server.

 

i can not thank you enough for your time and your help,

 

not only have you solved my problem but thanks to you and the other posters i have learned a lot! and that makes it a very good day 

 

very happy

 

thanks again :) 

 

5D107579B317D6692C95DF11A07BFCD285DEA384

 

7CEB70D9A55FD513CCB28D3E9CAC6449346A6CAE

 

  • Like 2

Share this post


Link to post
Share on other sites
On 9/1/2017 at 8:32 PM, das attorney said:

RemoteExec version (should work on local hosted as well as dedicated):


// init.sqf

if (isServer) then {
    fnc_setupTask = {
        // only setup the task once
        if (isNil "myTaskID") then {
            // set the task up here
            myTaskID = [
                "taskID",   // params
                true,   // target
                ["Get to the choppa","Do it","Do it nowwww"],   // desc
                HOOKDEVICE,  // dest
                "CREATED",  // state
                0,  // priority
                true,   // showNotification
                true,   // isGlobal
                "help", // type
                false   // shared
            ] call BIS_fnc_setTask;
        }
    }
};
if (hasInterface) then {
    0 spawn {
        waitUntil {time > 0};
        onEachFrame {
            // quit if already detected
            if (not isNil "TAG_DETECTED") exitWith {
                onEachFrame {}
            };
            // check what you are looking at
            private _ins = lineIntersectsSurfaces [
                AGLToASL positionCameraToWorld [0,0,0],
                AGLToASL positionCameraToWorld [0,0,1000],
                player
            ];
            // no intersection
            if (count _ins == 0) exitWith {};
            // if detected then tell everyone else to stop looking and tell the server to set up the task
            if (_ins select 0 select 3 isEqualTo HOOKDEVICE) then {
                TAG_DETECTED = true;
                publicVariable "TAG_DETECTED";
                TAG_DETECTED remoteExec [
                    "fnc_setupTask",
                    2
                ]
            }
        }
    }
};

 

My apologies on dredging up an old post.
How would one go about making this task complete within this code structure, once HOOKDEVICE was destroyed? 
Cheers.

Share this post


Link to post
Share on other sites
4 hours ago, pierremgi said:

How is hooked the device? Is simulation enabled? How do you destroy it?

Hi mate thanks for the reply.

In my case it's not a device, rather an unit called triggerMan. And he is killed via sniper. Everything in above code works, just not sure how to complete the task that is created in the first bit of the code.

Share this post


Link to post
Share on other sites

In this case, it's  simple. In Init.sqf


 

fnc_setupTask = {
  if (!isServer) exitWith {true};
  params ["_target"];
  if (isNil "myTaskID") then {
    task1000 = [
      "taskID1000",
      true,
      ["Get to the choppa","Do it","Do it nowwww"],
      _target,
      "CREATED",
      0,
      true,
      true,
      "help",
      false
    ] call BIS_fnc_setTask;
    waitUntil {sleep 2; !alive _target};
    ["taskID1000","SUCCEEDED"] call BIS_fnc_taskSetState


  }
};

if (hasInterface) then {
  HOOKDEVICE spawn {
    params ["_target"];
    while {isnil {_target getVariable "TAG_DETECTED"} && alive _target} do {
      if (cursorObject isEqualTo _target) exitWith {
        _target setVariable ["TAG_DETECTED",true,true];
        _target remoteExec ["fnc_setupTask",2];
      };
      sleep 1;
    };

  };
};

No reason for more complex code. You can change HOOKDEVICE for the name of your unit.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
5 minutes ago, pierremgi said:

In this case, it's  simple. In Init.sqf


 


fnc_setupTask = {
  if (!isServer) exitWith {true};
  params ["_target"];
  if (isNil "myTaskID") then {
    task1000 = [
      "taskID1000",
      true,
      ["Get to the choppa","Do it","Do it nowwww"],
      _target,
      "CREATED",
      0,
      true,
      true,
      "help",
      false
    ] call BIS_fnc_setTask;
    waitUntil {sleep 2; !alive _target};
    ["taskID1000","SUCCEEDED"] call BIS_fnc_taskSetState


  }
};

if (hasInterface) then {
  HOOKDEVICE spawn {
    params ["_target"];
    while {isnil {_target getVariable "TAG_DETECTED"} && alive _target} do {
      if (cursorObject isEqualTo _target) exitWith {
        _target setVariable ["TAG_DETECTED",true,true];
        _target remoteExec ["fnc_setupTask",2];
      };
      sleep 1;
    };

  };
};

No reason for more complex code. You can change HOOKDEVICE for the name of your unit.

Thank you very much sir! It works perfectly.
 

Share this post


Link to post
Share on other sites

I have used this script in my own mission, and am thankful it exists!

Have a technical question on how it works-
Because I couldn't get it to work with a texture object. Only "physics" rendered ones. Is there any reason why lineIntersectsSurfaces wouldn't work with texture objects?

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

×