Jump to content
Sign in to follow this  
wiggum2

Why is "mygroup = group this" not working ??

Recommended Posts

Hi,

i have a really strange bug or problem with ArmA2 CO 1.59 (also tryed the current BETA).

I disabled all mods to make sure this is not a problem of some addon !

I place 3 units and group them, make myselfe the leader.

I add to the Player unit init -> mygroup = group this;

Then i make a trigger with the condition:

{alive_x} count units mygroup == 0

On Activation:

hint "Why is mygroup == 0 ??";

Now i start the game and the trigger fires...really starnge !

I also tried it with a script:

_mygroup = _this select 0;

waitUntil {not isNil{_mygroup}};

hint "mygroup is alive !!";

...but i never see the hint...

Here is a example mission, try it yourselfe and tell me if you get the hint or not:

http://www.file-upload.net/download-3752814/grouptest.zip.html

Edited by Wiggum

Share this post


Link to post
Share on other sites

Without testing it looks like it's because your are missing a space:

{aliv[color="Red"]e_[/color]x} count units mygroup == 0

This might cause the result to be nil or something that is not true and thus noone get's counted.

Otherwise the issue might be that groups are initialized after units are.

EDIT:

Without the spelling error above it works fine here.

Edited by Muzzleflash

Share this post


Link to post
Share on other sites

You need to start using squint to filter the basic coding errors. It will save you a lot of time.

Share this post


Link to post
Share on other sites

Ok, the ingame trigger fires...sorry for the missing space.

But the script still does not work:

_patrolpos = _this select 0;
_areaname  = _this select 1;
_areasize  = _this select 2;
_grphunter = _this select 3;
[color="Red"]_grptarget = _this select 4[/color];

_eastmen = nearestobjects [_areaname,["SoldierEB"],_areasize];
_westmen = nearestobjects [_areaname,["SoldierWB"],_areasize];

_formation = ["WEDGE", "ECH LEFT", "ECH RIGHT", "VEE", "DIAMOND"] call BIS_fnc_selectRandom;
_speed = ["NORMAL", "FULL"] call BIS_fnc_selectRandom;
_behaviour = ["AWARE", "COMBAT"] call BIS_fnc_selectRandom;
_mode = ["YELLOW", "RED"] call BIS_fnc_selectRandom;

private ["_myVariable", "_myVariable2", "_patrol", "_hunt"];
_myVariable = 0;
_myVariable2 = 0;

[color="Red"]waitUntil {not isNil{_grptarget}};[/color]

_patrol = [_grphunter, position _patrolpos, 300, 7, "MOVE", "SAFE", "YELLOW", "LIMITED", "STAG COLUMN", "", [2,5,10]] call CBA_fnc_taskPatrol;
hint "Patroling";

while {({alive _x} count units _grphunter > 0)} do {


if ({_x knowsAbout ({_x} forEach _westmen) <= 1.3} count _eastmen > 0) then {
{ 
_temp = _x;
{_temp reveal _x}  foreach _westmen;
} foreach  _eastmen;
sleep 5;
};


if (({_x knowsAbout ({_x} forEach _westmen) > 1.3} count _eastmen > 0) && ({alive _x} count units _grptarget > 0) && (_myVariable == 0)) then {
terminate _patrol;
sleep 1;
_myVariable = 1;
{_x setBehaviour _behaviour; _x setCombatMode _mode; _x setSpeedMode _speed; _x setFormation _formation} foreach units _grphunter;
};

if (_myVariable == 1) then {
_grphunter move getpos leader _grptarget;
hint "Hunting";
sleep 20;
};

if (({alive _x} count units _grptarget == 0) && (_myVariable2 == 0)) then {
_myVariable = 0;
terminate _hunt;
sleep 1;
_patrol = [_grphunter, position _patrolpos, 300, 7, "MOVE", "SAFE", "RED", "LIMITED", "STAG COLUMN", "", [2,5,10]] call CBA_fnc_taskPatrol;
_myVariable2 = 1;
hint "Patroling";
};


};

The script never gets beyond the "waituntil".

The script is called with:

nul=[pos1,this,500,group this,mygroup] execVM "hunting_patrol.sqf";

Edited by Wiggum

Share this post


Link to post
Share on other sites

Sorry for that, just a typo here. The script itselfe is fine and still it does not work ! :confused:

Share this post


Link to post
Share on other sites

Where do you start this script? Looks like an init due to the nul = .... This init might be run before the mygroup init.

Share this post


Link to post
Share on other sites

Script is called from a groupleaders init.

EDIT:

Running the script from a trigger with CONDITION -> true solves the problem !

So i guess that running the script from the init will not work, but there are many similar patrol scripts that run from a groupleaders init...

Edited by Wiggum

Share this post


Link to post
Share on other sites

Are both the mygroup and script started from the same init? Does the mygroup = group this; come before the script spawning then?

Try inserting:

hint str _grptarget;

on line six just after you read the parameters. What does it say?

Share this post


Link to post
Share on other sites

mygroup is the name of a BLUFOR group, thats the _grptarget.

The script is called from a OPFOR groupleader's init.

hint str _grptarget;

No hint shows if script is called from inside the OPFOR groupleader's init.

When called from a trigger then it shows "B-1-1" or similar.

Edited by Wiggum

Share this post


Link to post
Share on other sites

Glad you got it working :). You still need to fix this though:

if ([color="Red"]({_x knowsAbout ({_x} forEach _westmen) > 1.3} count _eastmen > 0)[/color] && ({alive _x} count units _grptarget > 0) && (_myVariable == 0)) then {

So i guess that running the script from the init will not work, but there are many similar patrol scripts that run from a groupleaders init...

Many run scripts from inits but it can be quite dangerous. Often they are "saved" because of the locality of some of the most common commands.

Things to be aware of when using inits:

- You cannot rely on the order in which init's are run in. Well think you "may" be able to if you check the order in the mission.sqm but better not leave it to chance.

- Init's run for everyone!! I notice that you do not have an isServer in your init or your script. That means that the script will be started for all players. If the commands you use are global, like setPos, then this can have undesirable consequences since N players + server attempts to tell your group what to do.

- Init's are not run for playable units which noone have selected (if you don't use AI's for those slots ofc). So don't put critical mission stuff in inits of units that might not be picked. Exception is JIP players. Init can be destructive here also since an init you though was only run on mission start will also run for JIP's. JIPs also run everybody's inits not just their own when they join.

Example where people are "saved" by locality: addWeapon and addMagazine. addMagazine only works where the unit is local. If it did not units would get extra magazines for each player joining.

Edited by Muzzleflash

Share this post


Link to post
Share on other sites

Thanks for the advise, never know about that ! :)

I will use a if (!isServer) exitwith {}; in the final version.

if ([color="Red"]({_x knowsAbout ({_x} forEach _westmen) > 1.3} count _eastmen > 0)[/color] && ({alive _x} count units _grptarget > 0) && (_myVariable == 0)) then {

Whats wrong with that ?

Got it from that thread:

http://forums.bistudio.com/showthread.php?t=102376

Share this post


Link to post
Share on other sites

The value of the last expression is the result. Let's divide this up to see how it works:

({_x knowsAbout ({_x} forEach _westmen) > 1.3} count _eastmen > 0)

This is what you put in the right side of knowsAbout:

({_x} forEach _westmen)

Basically it just have a "hidden" result of each item in the array. For an array [A, B, C] the result is

A

B

C

However, the results are not really used for anything. Now the result of

({_x} forEach _westmen)

becomes the value of the last expression which was C. If it is not C then it is nil not quite sure. Let's just say C:

({_x knowsAbout C > 1.3} count _eastmen > 0)

So for each east unit you end up checking the whether it knows more than 1.3 about the last, only the last, unit in _westmen.

This should probably work and looks simpler in my eyes than one long liner:

_eastKnowsWest = false;
{
   _eMan = _x;
   if ( {_eMan knowsAbout _x > 1.3} count _westmen > 0 ) exitWith {_eastKnowsWest = true;};
} forEach _eastmen;

Then your if becomes:

if ( _eastKnowsWest && ({alive _x} count units _grptarget > 0) && (_myVariable == 0)) then {

Squint also validates this. It did not validate it before. This applies to both line 27 and 36.

Edited by Muzzleflash

Share this post


Link to post
Share on other sites

@Wiggum:

Did you see my last post in your last thread? The reason _grptarget wasn't being assigned until you tried the true trigger method is because the script was started before the variable mygroup was set. All init fields run in the order in which the units/objects were added to the editor, so it must be the case that the init field you had executing the script was on a unit/object that had been placed before the unit/object whose init field assigned the mygroup variable. As I said in your last thread, you could have circumvented this issue by putting a one second (probably a tenth of a second would be sufficient to be honest) delay at the very beginning of your script. This would allow all init fields time to complete before the local variables within the script were assigned.

---------- Post added at 09:24 AM ---------- Previous post was at 09:17 AM ----------

- You cannot rely on the order in which init's are run in. Well think you "may" be able to if you check the order in the mission.sqm but better not leave it to chance.

- Init's run for everyone!! I notice that you do not have an isServer in your init or your script. That means that the script will be started for all players. If the commands you use are global, like setPos, then this can have undesirable consequences since N players + server attempts to tell your group what to do.

You can rely on the order in which inits are run. They are always run in the order in which the objects were placed in the editor. As long as you keep track of this, you will know the order.

Your advice on locality is generally good advice although I am unsure as to how running setPos globally is problematic. It's a little inefficient maybe, but the end result will be no different than if it were only run on one machine. JIPs could cause a (potentially funny) problem, though. :p

Share this post


Link to post
Share on other sites
As I said in your last thread, you could have circumvented this issue by putting a one second (probably a tenth of a second would be sufficient to be honest) delay at the very beginning of your script. This would allow all init fields time to complete before the local variables within the script were assigned.

I already tried to add a delay at the beginning of the script with no success.

The problem is that if the script is called from the init of a unit it may will report _grptarget as nil because the init of the groupleader from _grptarget comes later. A delay at the beginning of the script does nothing to solve this because _grptarget is already reported as nil.

At least i think so... ;)

Quick question:

while {party} do [color="Red"]{[/color]
If (itrains) then [color="Blue"]{[/color]
[b]waitUntil {itstopstorain};[/b]
hint "Nr 1";
[color="Blue"]};[/color]
hint "Nr 2";
[color="Red"]};[/color]

Now, will the waitUntil in this example hold the whole script till "itstopstorain" is true ?

Will the hint Nr. 2 only show up if "itstopstorain" is true or is only hint Nr. 1 affected ?

Edited by Wiggum

Share this post


Link to post
Share on other sites
I already tried to add a delay at the beginning of the script with no success.

The problem is that if the script is called from the init of a unit it may will report _grptarget as nil because the init of the groupleader from _grptarget comes later. A delay at the beginning of the script does nothing to solve this because _grptarget is already reported as nil.

Oh yeah actually that's right since you are passing mygroup before mygroup exists. You could get around that by passing "mygroup" (in quotes) and compiling it in the script, but it's moot at this point anyway.

As far as your quick question:

The waitUntil will hold the whole script if itrains is true. If itrains is false or undefined, the waitUntil will not be run at all, so the script will continue with hint "Nr 2".

Share this post


Link to post
Share on other sites

There are a few more things I noticed with the script.

There's a mixture of units in an area ie _westmen, _eastmen and defined Groups passed, this is kind of redundant if your just moving defined groups there is no reason to mess with single units as your doing nothing with them apart from just upping reveal to 1.

There is a terminate _patrol command which doesn't seem to work. I've tried before and it doesn't seem to work on functions.

The script will move the units to the prey but there may be some conflict between the script and patrol function. This will probably just show as some messing about.

Actually I just checked an you can terminate a function but in this case it doesn't seem to work or maybe it does it's just that there maybe a load of waypoints that need to be completed before you can see them stop patrolling.

That dose seem to be the case, even if you remove all waypoints created by _patrol the Group still want to complete the current waypoint so there seems little point in disabling _patrol

Edited by F2k Sel

Share this post


Link to post
Share on other sites

You are correct !

Sometimes the patrol cant be stoped, or it will result in strange behaviour like the group never leaving the "SAFE" "LIMITED" behaviour fromthe patrol but actually hunting the target.

Any idea ?

EDIT:

Maybe not perfect but it seems to work:

terminate _patrol;
sleep 1;
// Just to really terminate _patrol
[color="SeaGreen"]_attack = [_grphunter] spawn CBA_fnc_searchNearby;[/color]
sleep 10;
[color="SeaGreen"]terminate _attack;[/color]

I just spawn this other function and delete it after 10 seconds, this really improved the behaviour of the enemy patrols. I have done 8 tests with my Demo mission and spotted no strange behaviour !

I hope it works...:pray:

Edited by Wiggum

Share this post


Link to post
Share on other sites

I'll try that later if I have no success.

Did you get multiple groups hunting?

Share this post


Link to post
Share on other sites

Yes, i tested it with 2 in my demo mission.

And i would not see a reason why it should not work with multiple groups...

My current version (with added flare function):

if (!isServer) exitwith {};

private ["_myVariable","_myVariable2","_patrol","_temp","_patrolpos","_areaname","_areasize","_grphunter","_grptarget","_eastmen","_westmen","_formation","_speed","_behaviour","_mode","_eastKnowsWest","_eMan","_flarecount","_ammo","_flare","_dir","_dist","_height","_li","_smokeeffect","_delay","_myVariable3","_patrolsize","_attack"];

_patrolpos = _this select 0;
_patrolsize = _this select 1;
_areaname = _this select 2;
_areasize = _this select 3;
_grphunter = _this select 4;
_grptarget = _this select 5;
_flarecount = _this select 6;

// Reveal stuff
// Maybe needs to be changed for some mods or DLC's !
_eastmen = nearestobjects [_areaname,["SoldierEB"],_areasize];
_westmen = nearestobjects [_areaname,["SoldierWB"],_areasize];

// Behaviour of the group while hunting
_formation = ["WEDGE", "ECH LEFT", "ECH RIGHT", "VEE", "DIAMOND"] call BIS_fnc_selectRandom;
_speed = ["NORMAL", "FULL"] call BIS_fnc_selectRandom;
_behaviour = ["AWARE", "COMBAT"] call BIS_fnc_selectRandom;
_mode = ["YELLOW", "RED"] call BIS_fnc_selectRandom;

// Flare ammo, delay and offset from shooter
_ammo = ["F_40mm_White", "F_40mm_Red"] call BIS_fnc_selectRandom;
_delay = 5 + random 3;
_dist = 15 + random 15;
_dir = random 360;

//Other Variables
_myVariable = 0;
_myVariable2 = 0;
_myVariable3 = 1;
_eastKnowsWest = 0;
_patrol = nil;
_attack = nil;

// Hint if groups are Nil
if ((isNil{_grptarget}) || (isNil{_grphunter})) then {
hint "You missed to define _grptarget or _grphunter ! Remember to call the script from a trigger !";
};

// Begin the patrol
_patrol = [_grphunter, position _patrolpos, _patrolsize, 7, "MOVE", "SAFE", "YELLOW", "LIMITED", "STAG COLUMN", "", [2,5,10]] call CBA_fnc_taskPatrol;
hint "Patroling";

// Start of loop
while {({alive _x} count units _grphunter > 0)} do {

// Delete flare light after !alive flare
if ((!alive _flare) && (_myVariable3 == 0)) then {
_myVariable3 = 1;
deleteVehicle _li;
};

//Share current informations with other groups 
if ( _eastKnowsWest == 0 ) then {
{ 
_temp = _x;
{_temp reveal _x}  foreach _westmen;
} foreach  _eastmen;
sleep 5;
};

// If someone is spotted set _eastKnowsWest = 1
{
_eMan = _x;
if ( {_eMan knowsAbout _x > 1.3} count _westmen > 0 ) exitWith {_eastKnowsWest = 1;};
} forEach _eastmen;

// If group knows about enemy and _grptarget is alive then stop patrol and switch behaviour
if (( _eastKnowsWest== 1) && ({alive _x} count units _grptarget > 0) && (_myVariable == 0)) then {
terminate _patrol;
sleep 1;
// Just to really terminate _patrol
_attack = [_grphunter] spawn CBA_fnc_searchNearby;
sleep 10;
terminate _attack;
_myVariable = 1;
sleep 1;
{_x setBehaviour _behaviour; _x setCombatMode _mode; _x setSpeedMode _speed; _x setFormation _formation} foreach units _grphunter;
};

// If group has flares and is close to _grptarget then shoot flare
if ((_flarecount!=0) && (leader _grphunter distance leader _grptarget <= 100) && (_myVariable3 == 1)) then {   
hint "Shooting flare";
sleep _delay;

_flare = _ammo createVehicle [(getPosASL leader _grphunter select 0) + (sin _dir) * _dist, (getPosASL leader _grphunter select 1) + (cos _dir) * _dist, _height];
leader _grphunter say ["flaregun",5];
_flarecount = _flarecount - 1;
_myVariable3 = 0; 

_li = "#lightpoint" createVehicleLocal [0,0,0];
_li setLightBrightness 0.24;
_li setLightAmbient[0.8, 0.4, 0.4];
_li setLightColor[0.8, 0.5, 0.5];
_li lightAttachObject [_flare, [0,0,0]];

BIS_Effects_Burn = compile preprocessFile "\ca\Data\ParticleEffects\SCRIPTS\destruction\burn.sqf"; 
_smokeeffect = [_flare, 0.6, time, false, false] spawn BIS_Effects_Burn;
_delay = _delay + random 5;
};

// Time to hunt !
if (_myVariable == 1) then {
_grphunter move getpos leader _grptarget;
hint "Hunting";
sleep 20;
};

// If _grptarget is dead then stop hunting and patrol again
if (({alive _x} count units _grptarget == 0) && (_myVariable2 == 0)) then {
_myVariable = 0;
sleep 1;
_patrol = [_grphunter, position _patrolpos, _patrolsize, 7, "MOVE", "SAFE", "RED", "LIMITED", "STAG COLUMN", "", [2,5,10]] call CBA_fnc_taskPatrol;
_myVariable2 = 1;
_eastKnowsWest = 0;
hint "Patroling again";
};

// End of loop
};

Edited by Wiggum

Share this post


Link to post
Share on other sites

I see.

I'm taking a new approach with all the counting and east westmen stuff removed.

It's much easier to read and working with multiple groups.

I've found a way to stop the patrol.

You need to remove the waypoints as in the other thread and to remove the current waypoint you have to move it to the leaders position so it allows it to complete.

terminate _patrol;
   while {(count (waypoints _hunters)) > 0} do  {
       deleteWaypoint [_hunters, 0];};
   [_hunters, 0] setWPPos getpos leader _hunters; 
} foreach  units _hunters;

_hunter in yours would probably be _grphunter

Edited by F2k Sel

Share this post


Link to post
Share on other sites
I see.

I'm taking a new approach with all the counting and east westmen stuff removed.

Can you post your version please ?

Share this post


Link to post
Share on other sites

I can this is a simplified version just working with named groups.

//
// null=[huntergrp,hunted] execvm "group_hunt.sqf"
// null=[huntergrp2,hunted] execvm "group_hunt.sqf" 

_formation = ["WEDGE", "ECH LEFT", "ECH RIGHT", "VEE", "DIAMOND"] call BIS_fnc_selectRandom;
_speed = ["NORMAL", "FULL"] call BIS_fnc_selectRandom;
_behaviour = ["AWARE", "COMBAT"] call BIS_fnc_selectRandom;
_mode = ["YELLOW", "RED"] call BIS_fnc_selectRandom;
_enemyspotted = 0;
_setuphunt  =  0;
_hunterstemp = 0;

_hunters = _this select 0;// group hunting
_prey  = _this select 1;  //  group being  hunted

// Assign Group to patrol
_patrol = [_hunters, position leader _hunters, 300, 7, "MOVE", "SAFE", "YELLOW", "LIMITED", "STAG COLUMN", "", [2,5,10]] call CBA_fnc_taskPatrol;
sleep random 3;
hint Format ["%1 Patrolling", str _hunters] ;

// main Loop
while {({alive _x} count units _hunters) > 0 and ({alive _x} count units _prey) > 0} do {
{ // do hunters know anything about prey and if so add 1 to knowsabout 
_hunterstemp = _x; 
{if ((_hunterstemp knowsabout _x) <= 1.3) then {_hunterstemp reveal _x;}}  foreach units _prey;
sleep 1;
} foreach  units _hunters;



{ // if any hunter in the group knows more than 1 about the prey then setup end patrol 
_hunterstemp = _x; 
   { // prey loop
    if ((_hunterstemp knowsabout _x) > 1 and (_enemyspotted == 0)) then {
_enemyspotted = 1;
terminate _patrol;
while {(count (waypoints _hunters)) > 0} do  {deleteWaypoint [_hunters, 0];};
       [_hunters, 0] setWPPos getpos leader _hunters; 
       }} foreach units _prey;
} foreach  units _hunters;

// set up hunt behaviour if enemy has been spotted and knows about is 1+	
if (_enemyspotted == 1 and _setuphunt == 0) then {
{_x setBehaviour _behaviour; _x setCombatMode _mode; _x setSpeedMode _speed; _x setFormation _formation }  foreach units _hunters;
_setuphunt = 1;
};

// start hunting
if (_enemyspotted == 1) then {
_hunters move getpos leader _prey;
 hint Format ["%1 Hunting", str _hunters];
sleep 20;
};
};// main loop exit


// Script done Exiting
sleep 2;
if (({alive _x} count units _hunters) >0 ) then {
hint Format ["%1 Resuming Patrol", str _hunters];
_patrol = [_hunters, position leader _hunters, 300, 7, "MOVE", "SAFE", "YELLOW", "LIMITED", "STAG COLUMN", "", [2,5,10]] call CBA_fnc_taskPatrol;
} else {hint format ["Hunting Group %1 Killed",str _hunters];
};

Edited by F2k Sel

Share this post


Link to post
Share on other sites

Your version is working for sure...but... ;)

Men, i know it would be possible to get it work with multiple "targets"... (and then it would be really usefull !)

I tried attaching a object at the "nearestEnemy" and that worked, but the problem is...what if there are enemys visible only to a specific group... :confused:

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
Sign in to follow this  

×