Dielos 0 Posted April 6, 2010 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
rübe 127 Posted April 6, 2010 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
TRexian 0 Posted April 6, 2010 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
Dielos 0 Posted April 6, 2010 (edited) 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 April 6, 2010 by Dielos Problem Share this post Link to post Share on other sites