Jump to content
Sign in to follow this  
fatty86

Moving Multiple Objects/Units to Random Locations

Recommended Posts

I have gotten a handle on using random locations for small objectives, like weapons crates to be destroyed, etc. With a set of gamelogics identifying possible positions, it's a simple two step process:

1. Short random number script selects one of the gamelogics at random.

2. The crate is setpos'd to that game logic.

This is rather limiting to the size of the objective, as I can only move one object at a time. What I'd like to try to do is set up larger objectives at random locations, such as a base etc. with multiple objectives and multiple defenders. I can think of two ways to do this:

1. Give each object/unit its own dedicated set of gamelogics at each possible location. I think this would be very tedious to set up. For a very small base with 12 objects and 8 defending units (20 entitites total) and three possible locations, you'd be looking at 3x20=60 game logics to create and place.

2. Use setpos to set the positions of each object relative to the gamelogic. This too would be tedious, as it'd require a lot of trial-and-error to make sure the units are exactly where they need to be.

So what I'd like to know is if there is an easier way to effectivel 'transplant' all the objects/units from one location and drop them somewhere else, with their positions relative to each other intact?

Thanks for the help guys.

Share this post


Link to post
Share on other sites

Place Markers where you might want an object/unit to spawn. GROUP the markers with the object (might be easier to do this first since markers can be hard to find on the Group screen. In other words place the markers around a circle of your unit in open space, group them, then drag them where you want them.).

The object/unit will spawn in either at it's placed location or at the location of one of the grouped markers.

Share this post


Link to post
Share on other sites

If I use markers, will all units spawn at the same marker? And will their placements relative to each other stay intact at the new location?

Share this post


Link to post
Share on other sites

Oh, sorry, I'm exhausted and totally read that wrong. Umm.. you could do something similar to object compositions maybe? Or even just use those rather than hand place all the stuff. But no, markers wouldn't keep orientation or anything like that.

Share this post


Link to post
Share on other sites

Getting warmer shk, I like your approach. I wonder if it'd be possible to have a script scan a radius around a gamelogic for objects, and then move those objects to a new location. That way the naming of the objects wouldn't matter for building larger, more complicated bases.

Edited by fatty86

Share this post


Link to post
Share on other sites

It's probably possible, I'll do some tests once I get home from work.

---------- Post added at 07:24 AM ---------- Previous post was at 06:25 AM ----------

Do some testing, I don't know what types of stuff the nearobjects command in/excludes.

nul = [gl1,gl2,50] execvm "shk_moveobjects.sqf"

private ["_anchor","_destination","_range","_objects","_aPos","_dPos","_xPos","_dir","_dist"];
_anchor = _this select 0;
_destination = _this select 1;
_range = _this select 2;

_aPos = getpos _anchor;
_dPos = getpos _destination;
_objects = _aPos nearobjects _range;
{
 _xPos = getpos _x;
 _dir = ((_xPos select 0) - (_aPos select 0)) atan2 ((_xPos select 1) - (_aPos select 1));
 _dist = _aPos distance _xPos;
 _x setpos [((_dPos select 0) + (_dist * sin _dir)),
           ((_dPos select 1) + (_dist * cos _dir)),
           0];
} foreach _objects;

Edited by Shuko

Share this post


Link to post
Share on other sites

And another version, with more parameters:

/*
 SHK_moveObjects
 Author: Shuko (miika.jarvinen@pp3.inet.fi, shuko@quakenet)
 Version 0.2

 Moves set of objects from A to B, retaining the direction and distance from
 a point of reference.

 Parameters:
   0: Object or Position   Anchor, point of origin.
   1: Object or Position   Center position to which objects are move around.
   2: Number               Range in meters to search for objects.
   3: Array or String      Optional. Type of objects to search for.

 Examples:
   nul = [gl1,gl2,50] execvm "shk_moveobjects.sqf"
   nul = [start,destination,100,"Man"] execvm "shk_moveobjects.sqf"
   nul = [[3243,5234,0],gl2,50,["Man","Car"]] execvm "shk_moveobjects.sqf"

*/
private ["_range","_objects","_aPos","_dPos","_xPos","_dir","_dst","_types"];
_aPos = _this select 0;
_dPos = _this select 1;
_range = _this select 2;
if (count _this > 3) then {_types = _this select 3};

if (typename _aPos == typename objNull) then {_aPos = getpos _aPos};
if (typename _dPos == typename objNull) then {_dPos = getpos _dPos};

_objects = [];

if (isnil "_types") then {
 _objects = _aPos nearobjects _range;
} else {
 if (typename _types == typename "") then {
   _objects = _aPos nearobjects [_types,_range];
 } else {
   {
     _objects = _objects + (_aPos nearobjects [_x,_range]);
   } foreach _types;
 };
};

{
 _xPos = getpos _x;
 _dir = ((_xPos select 0) - (_aPos select 0)) atan2 ((_xPos select 1) - (_aPos select 1));
 _dst = _aPos distance _xPos;
 _x setpos [((_dPos select 0) + (_dst * sin _dir)),
           ((_dPos select 1) + (_dst * cos _dir)),
           0];
} foreach _objects;

Share this post


Link to post
Share on other sites

shk you're a damned genius. A Finnish superhero. Can't wait to get home and try this.

Share this post


Link to post
Share on other sites

Well, here's the latest version. Replaced the usage of nearobjects with nearestobjects to get a tidier code. :P

private ["_range","_objects","_aPos","_dPos","_xPos","_dir","_dst","_types"];
_aPos = _this select 0;
_dPos = _this select 1;
_range = _this select 2;
_types = if (count _this > 3) then {_this select 3} else {[]};

if (typename _aPos == typename objNull) then {_aPos = getpos _aPos};
if (typename _dPos == typename objNull) then {_dPos = getpos _dPos};
if (typename _types == typename "") then {_types = [_types]};

_objects = nearestobjects [_aPos,_types,_range];

{
 _xPos = getpos _x;
 _dir = ((_xPos select 0) - (_aPos select 0)) atan2 ((_xPos select 1) - (_aPos select 1));
 _dst = _aPos distance _xPos;
 _x setpos [((_dPos select 0) + (_dst * sin _dir)),
           ((_dPos select 1) + (_dst * cos _dir)),
           0];
} foreach _objects;

Share this post


Link to post
Share on other sites

Works a charm in the editor, will have to try it out in a dedicated next. For anyone else interested, here's what I've got:

Objective: transplant a base to one of 3 possible random locations, to add randomness to mission objectives.

Build base with defending units as required, and place a game logic in the centre of it called obj. Then place three gamelogics at the possible locations, called objplace1, objplace2, and objplace3.

From init.sqf:

if (isServer) then
{
_random = floor(random 3);
_objplaces = [objplace1, objplace2, objplace3];
objdest = (_objplaces) select _random;
PublicVariable "objdest";
       nul = [obj,objdest,50] execvm "scripts\mover.sqf";
};

Mover.sqf is just shk's script above, specifically:

/*
 SHK_moveObjects
 Author: Shuko (miika.jarvinen@pp3.inet.fi, shuko@quakenet)
 Version 0.2

 Moves set of objects from A to B, retaining the direction and distance from
 a point of reference.

 Parameters:
   0: Object or Position   Anchor, point of origin.
   1: Object or Position   Center position to which objects are move around.
   2: Number               Range in meters to search for objects.
   3: Array or String      Optional. Type of objects to search for.

 Examples:
   nul = [gl1,gl2,50] execvm "shk_moveobjects.sqf"
   nul = [start,destination,100,"Man"] execvm "shk_moveobjects.sqf"
   nul = [[3243,5234,0],gl2,50,["Man","Car"]] execvm "shk_moveobjects.sqf"

*/
private ["_range","_objects","_aPos","_dPos","_xPos","_dir","_dst","_types"];
_aPos = _this select 0;
_dPos = _this select 1;
_range = _this select 2;
_types = if (count _this > 3) then {_this select 3} else {[]};

if (typename _aPos == typename objNull) then {_aPos = getpos _aPos};
if (typename _dPos == typename objNull) then {_dPos = getpos _dPos};
if (typename _types == typename "") then {_types = [_types]};

_objects = nearestobjects [_aPos,_types,_range];

{
 _xPos = getpos _x;
 _dir = ((_xPos select 0) - (_aPos select 0)) atan2 ((_xPos select 1) - (_aPos select 1));
 _dst = _aPos distance _xPos;
 _x setpos [((_dPos select 0) + (_dst * sin _dir)),
           ((_dPos select 1) + (_dst * cos _dir)),
           0];
} foreach _objects;

Share this post


Link to post
Share on other sites

This is awesome, nice work guys! I've been trying to find the perfect composition, then add markers, squads on various patrol scripts, etc, and this handles it all beautifully instead!:yay::yay::bounce3::bounce3:

Share this post


Link to post
Share on other sites

Shk, this seems to move triggers as well (intentional or are they some subclass of objects?) which is awesome! However markers do not seem to be moved (for instance as an objective marker, or for UPSMON patrol region markers). What needs to be done to this little ripper of a script to handle them as well? :man3:

Share this post


Link to post
Share on other sites

Yeah, you can even remove triggers with deletevehicle. Markers however are very simple things, unlike pretty much everything else, they are not objects. So, there is not much you can do to or with markers. And since theres no command to fetch markers, you need to do with more complex and annoying way of creating them with createmarker and saving them into array etc. :(

Share this post


Link to post
Share on other sites

This is such an excellent example, thanks so much guys. I have one question:

When the group created around the original 'obj' game logic spawns, they always keep their exact positions, so if you place a convoy running north - south they will always spawns that way no matter how you place the 'objplace1' gamelogics.

Can I get it so that their positions are maintained relative to their original placings, but they will rotate relative to the other 'objplace1' game logics? ie If I rotate the 'objplace1' so that the flag pole (or whatever) is face east - west, the objects will now face east - west?

Share this post


Link to post
Share on other sites

gnarly_rider, I didn't see your bump about markers a while back. Not sure if it's too late, but my solution is to simply setmarkerpos the marker that needs to be moved after the script has run.

Example:

if (isServer) then
{
_random = floor(random 3);
_objplaces = [cachepos1, cachepos2, cachepos3];
objdest = (_objplaces) select _random;
PublicVariable "objdest";
nul = [obj,objdest,50] execvm "scripts\mover.sqf";
};

"mkrTask2" setmarkerpos (getpos objdest);

Share this post


Link to post
Share on other sites
gnarly_rider, I didn't see your bump about markers a while back. Not sure if it's too late, but my solution is to simply setmarkerpos the marker that needs to be moved after the script has run.

Example:

if (isServer) then
{
_random = floor(random 3);
_objplaces = [cachepos1, cachepos2, cachepos3];
objdest = (_objplaces) select _random;
PublicVariable "objdest";
nul = [obj,objdest,50] execvm "scripts\mover.sqf";
};

"mkrTask2" setmarkerpos (getpos objdest);

No probs mate, that's exactly what I ended up doing! Cheers.

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  

×