Jump to content
Sign in to follow this  
Dielos

location "neighbors" variable

Recommended Posts

Hello,

I'm trying to find the neighbouring locations to a specific one in Chernarus. As per the wiki, all locations have a preset variable called "neighbors" which can be called with the getvariable command.

I find the location with the nearestlocation command and call the getvariable command with the result:

_neighbors = _location getvariable "neighbors"

But this always returns an error. I have also tried passing the name of the location without any result also.

Does anybody now how this works?

Thanks!

Share this post


Link to post
Share on other sites

Information like that isn't attached to some sort of object from which you could retrieve stuff with getVariable. Instead such "global" or world/island-information is organized in config files (see http://community.bistudio.com/wiki/configFile).

If you're new to this, you might wanna explore the config tree a bit, which can be quite inspiring. (though don't simply write a recursive function listing the whole tree, for this would take quite a while... hehe)

Now, what you're looking for is the CfgWorlds branch:

configFile >> "CfgWorlds" >> worldName >> "longitude"
configFile >> "CfgWorlds" >> worldName >> "latitude"
configFile >> "CfgWorlds" >> worldName >> "Ambient"
configFile >> "CfgWorlds" >> worldName >> "Armory"
configFile >> "CfgWorlds" >> worldName >> "Names"

You need to dig into "Names":

configFile >> "CfgWorlds" >> worldName >> "Names" >> name >> name
configFile >> "CfgWorlds" >> worldName >> "Names" >> name >> position
configFile >> "CfgWorlds" >> worldName >> "Names" >> name >> type
configFile >> "CfgWorlds" >> worldName >> "Names" >> name >> speech
configFile >> "CfgWorlds" >> worldName >> "Names" >> name >> radiusA
configFile >> "CfgWorlds" >> worldName >> "Names" >> name >> radiusB
configFile >> "CfgWorlds" >> worldName >> "Names" >> name >> angle

// the following entries exist only for "names" of the type CityCenter!
configFile >> "CfgWorlds" >> worldName >> "Names" >> name >> neighbors (array of location class names)
configFile >> "CfgWorlds" >> worldName >> "Names" >> name >> demography

Thus, you need to pick the config entry of the CityCenter you're interested in. To do that, I suggest you better not "hardcode" this query. Instead you might wanna write some neat generic config access function.

You may use the following function I've written for my own purposes. It's not really ideal for your task, since you wanna retrieve the information of exactly one CityCenter. But on the other hand, it's no big deal (overhead) to retrieve all CityCenters at the start of your mission:

// compile function
RUBE_extractConfigEntries = compile preprocessFileLineNumbers "RUBE\fn\fn_extractConfigEntries.sqf";

fn_extractConfigEntries.sqf:

/*
  Author:
   rübe

  Description:
   extracts config entries into an array with the use of custom
   selectors and a custom filter.

  Parameter(s):
   _this select 0: config/path (configFile/-Path)
   _this select 1: variables (array of strings/variable-names AND/OR 
                   code given the current class, returning any AND/OR
                   boolean to retrieve the current class itself (true) 
                   and the className (false))
   _this select 2: filter (function given the entry, returning boolean, 
                   optional)




  Example: (retrieves all CityCenters on the current island)

   // this will define the structure and contents of the arrays
   // we'll get back! (same order!)
   _cityCenterVariables = [
      false, // retrieve className
      true,  // retrieve the config itself
      "name", 
      "position", 
      // custom selector/manipulator:
      { 
        [
           (getNumber (_this >> "radiusA")), 
           (getNumber (_this >> "radiusB"))
        ] 
      },
      "type", 
      "speech",
      "neighbors",
      "demography"
   ];

   _cityCenterFilter = {
      if ((getText (_this >> "type")) in ["CityCenter"]) exitWith
      {
         true
      };
      false
   };

   _entries = [
      (configFile >> "CfgWorlds" >> worldName >> "Names"),
      _cityCenterVariables, 
      _cityCenterFilter
   ] call RUBE_extractConfigEntries;

   // (count _entries) == 46
   // (_entries select 0) returns:
   /-
      [
         "ACityC_Chernogorsk", 
         bin\config.bin/CfgWorlds/Chernarus/Names/ACityC_Chernogorsk, 
         "", 
         [6735.83,2626.6], 
         [100,100], 
         "CityCenter", 
         <null>, 
         ["ACityC_Prigorodki","ACityC_Balota","ACityC_Nadezhdino","ACityC_Mogilevka"], 
         ["CIV",1,"CIV_RU",0]
      ]
   -/


  Returns:
   array of config-entries with the desired variables in given order
*/

private ["_cfg", "_variables", "_filter", "_entries", "_extractValue", "_e"];

_cfg = _this select 0;
_variables = _this select 1;
_filter = { true };
_entries = [];

_extractValue = {
  if (isNumber _this) exitWith
  {
     (getNumber _this)
  };
  if (isText _this) exitWith
  {
     (getText _this)
  };
  if (isArray _this) exitWith
  {
     (getArray _this)
  };
  if (isClass _this) exitWith
  {
     private ["_c"];
     _c = [];
     for "_i" from 0 to ((count _this) - 1) do
     {
        _c = _c + [((_this select _i) call _extractValue)];
     };
     _c
  };
};

if ((count _this) > 2) then
{
  _filter = _this select 2;
};

for "_i" from 0 to ((count _cfg) - 1) do
{
  if ((_cfg select _i) call _filter) then
  {
     _e = [];
     {
        switch (typeName _x) do
        {
           // custom selector
           case "CODE":
           {
              _e = _e + [((_cfg select _i) call _x)];
           };
           // class selector/itself
           case "BOOL":
           {
              if (_x) then
              {
                 _e = _e + [(_cfg select _i)];
              } else {
                 _e = _e + [(configName (_cfg select _i))];
              };
           };
           // default selector
           default
           {
              _e = _e + [(((_cfg select _i) >> _x) call _extractValue)];
           };
        };
     } forEach _variables;

     _entries = _entries + [_e];
  };
};

_entries

Hope this helps.

Share this post


Link to post
Share on other sites

Wow ruebe - that is SLICK! :) I'll have to check out what you've done there!

Here's how I approached it for a mission where I wanted to select cities with 3 neighbors. It relies on the BIS locations module being on the map, IIRC.

// ================================== location functions ================
// get list of city centers
_list = ["CityCenter",[position player,10000],false] call bis_fnc_locations;


// get cities with 3 neighbors
waituntil {count _list > 0};

{
//hint format ["element %1 = %2", _x, getPos _x];
sleep .1;		// need this sleep apparently
_loc = getPos _x;
_typeVar = _x getVariable "type";
_neighbors = _x getVariable "neighbors";
_name = _x getVariable "name";

waituntil {!isNil _name};

	if (count _neighbors > 2) then
	{
	_listValid = _listValid + [_x];
	//sleep .1;
	};

} forEach _list;

You could re-work it so that it selected only the city that you wanted. Plus, you could output each loop entry to diag_log, figure out what the config name of the city is that you want, and just select that index.

Sorry if this isn't clear. :)

Share this post


Link to post
Share on other sites

Wow, thanks both of you!

It certainly is more complicated than I thought. I've never touched config files before, but it might be time to start learning them! I'll study both your systems, as I have to get to understand them first and then modify to what I want, but they do point me in the right direction!

What I want to do at the end is find west locations with neighbouring locations with side east.

Thanks again both of you!

[Edit]

Ok... TRexian, I started with your method as it's simpler for me right now. Calling bis_fnc_locations gives me all information I want, thanks! There is a problem, though. It fills me the map with citycenter markers and links between all towns, which is extremely cool, but I don't need them in my mission. I thought that with the debug option set to false, they wouldn't appear, but they do. It doesn't matter if it's set to true or false, the links always show. Is the debug option broken or am I doing something wrong?

Edited by Dielos
Problem

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  

×