Jump to content

Recommended Posts

Hey guys!

 

So I have this script I made:

Spoiler

params ["_caller"];

_callerGroup = group _caller;

{playMusic ""} forEach units group _callerGroup;

{hint "Fetching Quest..."} forEach units group _callerGroup;
{playSound "FD_Finish_F"} forEach units group _callerGroup;
_pos = [getPosATL _caller, 1000, 2000, 0, 0, 100	, 0] call BIS_fnc_findSafePos; // the first two numbers are the minimum and maximum range that the bandits spawn related to the players position
_eastGrp = createGroup east;
_tent = createVehicle ["CampEast", [_pos, 1, 3, 1, 0, 35, 0] call BIS_fnc_findSafePos, [], 0, "FORM"];
_tent enableSimulationGlobal false;
_tent allowDamage false;
_firePlace = createVehicle ["Campfire_burning_F", [_pos, 1, 3, 1, 0, 35, 0] call BIS_fnc_findSafePos, [], 0, "FORM"];

_music = ["CUP_A2_Cobalt","anomaly_07_05_v2","EventTrack02_F_Curator","Music_Failed_Contact_02","Music_Intro_03_MissionStart"] call BIS_fnc_selectRandom;

for "_i" from 1 to 2 +(floor(random 5)) do {
	_type = "Bandit_red";
 	_unit = _eastGrp createUnit [_type, _pos, [], 1, "FORM"];

 	removeAllWeapons _unit;
	removeAllItems _unit;
	removeAllAssignedItems _unit;
	removeUniform _unit;
	removeVest _unit;
	removeBackpack _unit;
	removeHeadgear _unit;
	removeGoggles _unit;

 	[_unit] call RVG_fnc_equip;
    [_unit] call HG_fnc_aiUnitSetup;
 	_unit setCombatMode "RED";
    _unit setBehaviour "SAFE";

};
[_eastGrp, _pos, 10] call BIS_fnc_taskPatrol;

[_callerGroup, "bounty", ["You've chosen to undertake this dangerous mission. A group of bandits have been causing trouble in the surrounding area. Deal with them.", "Bounty Hunt", ""], [_unit], "AUTOASSIGNED",1, true, "kill", false] call BIS_fnc_taskCreate;

playMusic _music;

0 = [_eastGrp] spawn {
Params ["_eastGrp","_tent","_firePlace"] ;
    waitUntil {({alive _x} count units _eastGrp) < 1};

    sleep 3;

    ["bounty", "SUCCEEDED", true] call BIS_fnc_taskSetState;
    {playMusic "CUP_A1_S_Sahrani_1"} forEach units group _callerGroup;
    {[200,0] call HG_fnc_addOrSubCash} forEach units group _callerGroup;
    {[50,0] call HG_fnc_addOrSubXP} forEach units group _callerGroup;
    {hint "Your survival prowess has gained you $200 and 50 XP!"} forEach units group _callerGroup;

    sleep 5;
    ["bounty", true] call BIS_fnc_deleteTask;

    sleep 600;

    {deleteVehicle _x} forEach _eastGrp;
    deleteVehicle _tent;
    deleteVehicle _firePlace;
};

0 = [_callerGroup] spawn {
Params ["_callerGroup","_eastGrp","_tent","_firePlace"] ;
    waitUntil {({alive _x} count units _callerGroup) < 1};
    ["bounty", "FAILED", true] call BIS_fnc_taskSetState;

    sleep 5;

    ["bounty", true] call BIS_fnc_deleteTask;
    {deleteVehicle _x} forEach _eastGrp;
    deleteVehicle _tent;
    deleteVehicle _firePlace;
};


 

 

I'm also using Ravage, hence the new functions and classnames.

 

What it does is as follows: When the script is triggered using the BIS_fnc_holdActionAdd function, the task will be created and it will spawn a small camp with AIs. Everything works like a charm in singleplayer or in multiplayer with ONE person. That includes the task complete/fail and everything works perfectly.

 

The problem arises when more than one person make use of the object which has the BIS_fnc_holdActionAdd function added onto it. It ends up creating a new task for all previous players who interacted with the object.

 

Object Init:

Spoiler

[ 
 this,            
 "Start Bounty Hunter Quest",           
 "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_forcerespawn_ca.paa",  
 "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_forcerespawn_ca.paa",  
 "_this distance _target < 3",       
 "_caller distance _target < 3",       
 {},              
 {},              
 {_caller execVM "scripts\world\tasks\bountyKill.sqf"},     
 {},              
 [],              
 3,              
 0,              
 false,             
 false             
] remoteExec ["BIS_fnc_holdActionAdd", 0, this];

 

 

How can I make it so that if I activate the task, and then another person activates the task, we both get different tasks instead of being reassigned the same one?

 

Any help will be greatly appreciated as I need this ASAP on my server! Thank you!

Share this post


Link to post
Share on other sites

I'm not good with locality.  

1 hour ago, MrCrazyDude115 said:

The problem arises when more than one person make use of the object which has the BIS_fnc_holdActionAdd function added onto it. It ends up creating a new task for all previous players who interacted with the object.

 

But it seems likely that previous players who interacted with object will no longer be near the object.  So you could add a "unit near object" test inside the bountyKill script.

 

Another option would be to create a missionNameSpace variable to hold array of players who have been assigned the quest.  This would be empty to start.  The bountyKill script would check at top if player in array, and if so exit.  If not, add the player to the array and do the rest of the script.   This should guarantee each player only assigned the quest once.    Good luck!

  • Thanks 1

Share this post


Link to post
Share on other sites
47 minutes ago, johnnyboy said:

I'm not good with locality.  

But it seems likely that previous players who interacted with object will no longer be near the object.  So you could add a "unit near object" test inside the bountyKill script.

 

Another option would be to create a missionNameSpace variable to hold array of players who have been assigned the quest.  This would be empty to start.  The bountyKill script would check at top if player in array, and if so exit.  If not, add the player to the array and do the rest of the script.   This should guarantee each player only assigned the quest once.    Good luck!

 

I see, but I think there's one thing you may have missed. Basically let's say I activated the quest and went to go complete it. If someone else tries to acquire a quest, it'll assign both of us HIS new quest. Along with HIS quest position (since its random).

Share this post


Link to post
Share on other sites
2 hours ago, MrCrazyDude115 said:

but I think there's one thing you may have missed. Basically let's say I activated the quest and went to go complete it. If someone else tries to acquire a quest, it'll assign both of us HIS new quest. Along with HIS quest position (since its random).

That shouldn't happen unless the the 2 players are in the same group (since the tasks are assigned to groups, not individual players.  If multiple players are in same group, then this explains your problem.

 

If your problem is locality (where the script is called for all players, instead of just the one player near the object), then my suggestions should work because even though the script is called incorrectly for multiple players, the script should exit immediately for the wrong players, and therefore only create task for desired player.

  • Like 1

Share this post


Link to post
Share on other sites
On 2/7/2020 at 6:45 PM, johnnyboy said:

I'm not good with locality.  

But it seems likely that previous players who interacted with object will no longer be near the object.  So you could add a "unit near object" test inside the bountyKill script.

 

Another option would be to create a missionNameSpace variable to hold array of players who have been assigned the quest.  This would be empty to start.  The bountyKill script would check at top if player in array, and if so exit.  If not, add the player to the array and do the rest of the script.   This should guarantee each player only assigned the quest once.    Good luck!

 

I hope this doesn't sound like a stupid question, but I'm not sure how to do that 😕

Share this post


Link to post
Share on other sites
On 2/7/2020 at 2:41 PM, MrCrazyDude115 said:

It ends up creating a new task for all previous players who interacted with the object.

No, it ends up making a new task for all players of the same group as the _caller.

 

On 2/7/2020 at 2:41 PM, MrCrazyDude115 said:

How can I make it so that if I activate the task, and then another person activates the task, we both get different tasks instead of being reassigned the same one?

Change the tasks owner to _caller rather than _callerGroup.

 

There is a lot of stuff here that does not make sense. Like all the {}forEach units _callerGroup. Most of the contents of these forEach structures either hint or play sound which are local effect meaning just the _caller will receive multiples.

I'm a little confused on what your are trying to accomplish. The above seems to indicate that you want the _callers group to all receive the task, hints and sounds, and the fact that you add the task for the _caller's group. Yet you say that it is not working correctly, as subsequent uses of the holdAction by other players resets previous players quests.

Maybe make the holdAction only available to the _caller and only if he is a group leader, then use task propagation to enable sharing of task with subordinates. Also add to the holdAction in the show condition a BIS_fnc_taskExists so if the _caller already has the task the holdAction cannot be used again until it has been completed and removed.

 

TLDR: Be more descriptive in how you expect your script to work in relation to groups, who receives the task and notifications( hint, sounds ) and who can initiate the holdAction.

 

  • Like 1

Share this post


Link to post
Share on other sites
15 hours ago, Larrow said:

No, it ends up making a new task for all players of the same group as the _caller.

 

Change the tasks owner to _caller rather than _callerGroup.

 

There is a lot of stuff here that does not make sense. Like all the {}forEach units _callerGroup. Most of the contents of these forEach structures either hint or play sound which are local effect meaning just the _caller will receive multiples.

I'm a little confused on what your are trying to accomplish. The above seems to indicate that you want the _callers group to all receive the task, hints and sounds, and the fact that you add the task for the _caller's group. Yet you say that it is not working correctly, as subsequent uses of the holdAction by other players resets previous players quests.

Maybe make the holdAction only available to the _caller and only if he is a group leader, then use task propagation to enable sharing of task with subordinates. Also add to the holdAction in the show condition a BIS_fnc_taskExists so if the _caller already has the task the holdAction cannot be used again until it has been completed and removed.

 

TLDR: Be more descriptive in how you expect your script to work in relation to groups, who receives the task and notifications( hint, sounds ) and who can initiate the holdAction.

 

 

Gotcha! Okay so here's how it is:

 

This is an open world survival scenario, so just because people are on the same side doesn't mean they're on the same "team". There are "quest boards" scattered around the map, and when a player interacts with the board they receive the task and the task itself is created. Now lets assume that player and his group went to complete the mission, and another random player decided to walk up to a board and activate it, ALL players who previously interacted with that board will be reassigned the new one that triggered when the second player used the board. Make sense?

 

I want to make it so that each player or each group has the task initialize locally so that it doesnt get overwritten by someone else.

Share this post


Link to post
Share on other sites

I also changed the code around a lot:

 

BountyKill.sqf

Spoiler

params ["_caller", "_unit"];

playMusic "";
hint "Fetching Quest...";
playSound "FD_Finish_F";

_pos = [getPosATL _caller, 1000, 2000, 0, 0, 100	, 0] call BIS_fnc_findSafePos; // the first two numbers are the minimum and maximum range that the bandits spawn related to the players position
_eastGrp = createGroup east;
_tent = createVehicle ["CampEast", [_pos, 1, 3, 1, 0, 35, 0] call BIS_fnc_findSafePos, [], 0, "FORM"];
_tent enableSimulationGlobal false;
_tent allowDamage false;
_firePlace = createVehicle ["Campfire_burning_F", [_pos, 1, 3, 1, 0, 35, 0] call BIS_fnc_findSafePos, [], 0, "FORM"];

_music = ["CUP_A2_Cobalt","anomaly_07_05_v2","EventTrack02_F_Curator","Music_Failed_Contact_02","Music_Intro_03_MissionStart"] call BIS_fnc_selectRandom;

for "_i" from 1 to 2 +(floor(random 5)) do {
	_type = "Bandit_red";
 	_unit = _eastGrp createUnit [_type, _pos, [], 1, "FORM"];

 	removeAllWeapons _unit;
	removeAllItems _unit;
	removeAllAssignedItems _unit;
	removeUniform _unit;
	removeVest _unit;
	removeBackpack _unit;
	removeHeadgear _unit;
	removeGoggles _unit;

 	[_unit] call RVG_fnc_equip;
 	_unit setCombatMode "RED";
    _unit setBehaviour "SAFE";

};
[_eastGrp, _pos, 10] call BIS_fnc_taskPatrol;

[_caller, "bounty", ["You've chosen to undertake this dangerous mission. A group of bandits have been causing trouble in the surrounding area. Deal with them.", "Bounty Hunt", ""], [_unit], "AUTOASSIGNED",1, false, "kill", false] call BIS_fnc_taskCreate;

playMusic _music;

_Cash = 200;
_XP = 50;
[_Cash, _XP, _eastGrp, _tent, _firePlace, _caller] remoteExecCall ["bountyReward", _caller, false];

 

 

QuestsInit.sqf

Spoiler


bountyReward =
{
    params ["_Cash", "_XP", "_eastGrp", "_tent", "_firePlace", "_callerGroup"];
    0 = [_eastGrp, _tent, _firePlace, _Cash, _XP] spawn
    {
        Params ["_eastGrp","_tent","_firePlace", "_Cash", "_XP"] ;
        waitUntil {({alive _x} count units _eastGrp) < 1};

        sleep 3;

        ["bounty", "SUCCEEDED", true] call BIS_fnc_taskSetState;

        playMusic "CUP_A1_S_Sahrani_1";
        [_Cash,0] call HG_fnc_addOrSubCash;
        [_XP,0] call HG_fnc_addOrSubXP;
        hint format["Your survival prowess has gained you $%1 and %2 XP!", _Cash, _XP];

        sleep 5;
        ["bounty", true] call BIS_fnc_deleteTask;

        sleep 600;

        {deleteVehicle _x} forEach _eastGrp;
        deleteVehicle _tent;
        deleteVehicle _firePlace;
    };

    0 = [_callerGroup, _eastGrp, _tent, _firePlace] spawn
    {
        Params ["_callerGroup","_eastGrp","_tent","_firePlace"] ;
        waitUntil {({alive _x} count units _callerGroup) < 1};
        ["bounty", "FAILED", true] call BIS_fnc_taskSetState;

        sleep 5;

        ["bounty", true] call BIS_fnc_deleteTask;
        {deleteVehicle _x} forEach _eastGrp;
        deleteVehicle _tent;
        deleteVehicle _firePlace;
    };
};

 

 

So.. what do I do from here to achieve the desired outcome I described in the previous post?

Share this post


Link to post
Share on other sites
15 hours ago, MrCrazyDude115 said:

Now lets assume that player and his group went to complete the mission, and another random player decided to walk up to a board and activate it, ALL players who previously interacted with that board will be reassigned the new one that triggered when the second player used the board. Make sense?

From your OP this could never happen unless the player who used the holdAction was in the same group.

As it is a survival mode maybe make all players have their own group and give them some way to group up if they want.

 

Spoiler

//Object init

[ 
	this,
	"Start Bounty Hunter Quest",
	"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_forcerespawn_ca.paa",
	"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_forcerespawn_ca.paa",
	//Can only use if they have not already got the task
	"_this distance _target < 3 && { !( [ format[ 'bounty_%1', groupId group _this ] ] call BIS_fnc_taskExists ) }",
	//Just incase another group member starts the task
	"_caller distance _target < 3 && { !( [ format[ 'bounty_%1', groupId group _caller ] ] call BIS_fnc_taskExists ) }",
	{},
	{},
	//_this, just pass the whole parameter array
	{_this execVM "scripts\world\tasks\bountyKill.sqf"},
	{},
	[],
	3,
	0,
	false,
	false,
	true
] call BIS_fnc_holdActionAdd; //No remoteExec, init is called for each client when the map is loaded

//bountyKill.sqf

//parameters passed from holdAction
params[ "", "_caller" ];

//This only happens for _caller
playMusic "";
hint "Fetching Quest...";
playSound "FD_Finish_F";

//Create mission objectives
_pos = [ getPosATL _caller, 1000, 2000, 0, 0, 100, 0 ] call BIS_fnc_findSafePos; // the first two numbers are the minimum and maximum range that the bandits spawn related to the players position

_tent = createVehicle[ "CampEast", [ _pos, 1, 3, 1, 0, 35, 0 ] call BIS_fnc_findSafePos, [], 0, "FORM" ];
_tent enableSimulationGlobal false;
_tent allowDamage false;

_firePlace = createVehicle[ "Campfire_burning_F", [ _pos, 1, 3, 1, 0, 35, 0 ] call BIS_fnc_findSafePos, [], 0, "FORM" ];

_eastGrp = createGroup east;
for "_i" from 1 to ( 2 + floor random 5 ) do {
	_unit = _eastGrp createUnit[ "Bandit_red", _pos, [], 1, "FORM" ];

	removeAllWeapons _unit;
	removeAllItems _unit;
	removeAllAssignedItems _unit;
	removeUniform _unit;
	removeVest _unit;
	removeBackpack _unit;
	removeHeadgear _unit;
	removeGoggles _unit;

	[_unit] call RVG_fnc_equip;
	_unit setCombatMode "RED";
	_unit setBehaviour "SAFE";

};
[ _eastGrp, _pos, 10 ] call BIS_fnc_taskPatrol;

//Add a task with unique taskID to _caller's group
_callerGroup = group _caller;
_taskID = format[ "bounty_%1", groupId _callerGroup ];
[ _callerGroup, _taskID, [ "You've chosen to undertake this dangerous mission. A group of bandits have been causing trouble in the surrounding area. Deal with them.", "Bounty Hunt", "" ], [ _tent, true ], "AUTOASSIGNED", 1, true, "kill", false ] call BIS_fnc_taskCreate;

//remote playMusic on all players belonging to the _caller's group
selectRandom[ "CUP_A2_Cobalt", "anomaly_07_05_v2", "EventTrack02_F_Curator", "Music_Failed_Contact_02", "Music_Intro_03_MissionStart" ] remoteExec [ "playMusic", group _caller ];

_cash = 200;
_xp = 50;

_missionSuccess = false;
waitUntil{
	sleep 5;
	_missionSuccess = { alive _x }count units _eastGrp isEqualTo 0;
	_missionSuccess || { { alive _x }count units _callerGroup isEqualTo 0 }
};

if ( _missionSuccess ) then {
	//End specific _taskID
	[ _taskID, "SUCCEEDED", true ] call BIS_fnc_taskSetState;
	//Reward all players of _caller's group
	[ _cash, _xp ] remoteExec[ "MCD_fnc_taskBountySucceeded", _callerGroup ];
}else{
	//End specific _taskID
	[ _taskID, "FAILED", true ] call BIS_fnc_taskSetState;
};

sleep 5;

//Delete specific _taskID
[ _taskID, true ] call BIS_fnc_deleteTask;

//Wait until all members of the _caller's group are > 200m away from the _tent
waitUntil{ sleep 5; { _x distanceSqr _tent < ( 200^2 ) }count units _callerGroup isEqualTo 0 };

//Delete task objectives
{ deleteVehicle _x }forEach _eastGrp;
deleteGroup _eastGrp; //Clean up the group
deleteVehicle _tent;
deleteVehicle _firePlace;

//initPlayerLocal.sqf

//MCD = MrCrazyDude
//Function called remotely on task completion
MCD_fnc_taskBountySucceeded = {
	params[ "_cash", "_xp" ];
	
	playMusic "CUP_A1_S_Sahrani_1";
	
	//Not sure of locality of HallyG's scripts, would presume local effect
	[ _cash, 0 ] call HG_fnc_addOrSubCash;
	[ _xp, 0 ] call HG_fnc_addOrSubXP;
	
	hint format[ "Your survival prowess has gained you $%1 and %2 XP!", _cash, _xp ];
};

All thoroughly untested.

 

Using a generic 'bounty' as a taskID wil likely cause you problems as BIS_fnc_taskSetState will only set this specific ID.

If all players using the quest board, no matter their group, all get a task with ID of 'bounty' then taskSetState will effect all. So I have used the groupID concatenated on the end of bounty to make the taskID specific to the group that picked up the task.

 

Think that works out right, let me know how you get on.

If a player using the holdAction still overwrites other players current task then your players are all in the same group.

 

  • Thanks 1

Share this post


Link to post
Share on other sites

Aha! Okay everything works except for the reward function in initPlayerLocal.

 

4jraFTa.jpg

Share this post


Link to post
Share on other sites
14 minutes ago, MrCrazyDude115 said:

Aha! Okay everything works except for the reward function in initPlayerLocal.

Hidden character from copy and pasting from forum post? Known forum bug.

Share this post


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

Hidden character from copy and pasting from forum post? Known forum bug.

 

Hmmm... I'm looking at it but I don't see anything I can tell is missing. Any ideas?

Share this post


Link to post
Share on other sites
2 minutes ago, MrCrazyDude115 said:

I can tell is missing

Not missing literally an invisible character.

It is saying the error is at the end of the playMusic line ( where the # is at in your screen shot ). Place your cursor before the proceeding ; and delete all the way to before [ _cash

Then just add a ; and return to add a line break. See if that fixes it.

  • Thanks 1

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

×