Taurus 20 Posted June 28, 2007 Is there a dynamic or generic way to get town names? Like you do with player name name player This as I from time to time fly over Sahrani to find a good place for a mission. i.e. I fly over a town and I get Welcome to blabla! Instead of pressing "m" to open the map. Thanks in advance! Share this post Link to post Share on other sites
tj72 0 Posted June 28, 2007 Only way besides big triggers that have side present condition yourname inthis list trig1... would be to put game logics in the map at the towns ahead of time. Name each logic after its town. then have a script with: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> ;checktowns.sqs ;Variable for the distance from a town before you get the hint TownRadius = 200 @ choppername distance Cayologic1 < TownRadius: hint "welcome to Cayo" then you can tweak TownRadius for all the checks for each logic. Im not sure what this will do to CPU usage but I think @ is less cycles used than the triggers. The problem with this idea is that @ will wait for that condition alone before going to the next check so you would need seperate scripts for each logic. For me, this wouldnt be too bad because I would just make a nested directory for this library of scripts and then be done. But Ive never done this so it might lag terribly. So a while do loop in .sqf that checks these distances, all, on a constant basis would then work all in one script and not require a fleet of little scripts running. In sqs form: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> ;TownCheck.sqs #START ? choppername distance Cayologic < TownRadius: hint "Welcome to Cayo ? choppername distance Paraisologic < TownRadius: hint "Welcome to Paraiso" and so on.... OK so now this will work but once your in range the thing will keep on looping so now you have to exit the script so I will change the script with: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> @ choppername distance Cayologic1 < TownRadius: hint "welcome to Cayo" ? choppername distance Cayologic < TownRadius: [Cayologic,0] exec "wait_til_gone.sqs" ? choppername distance Cayologic < TownRadius: goto  "END" So there is a block of this code for every logic/town involved. then in the new script: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> ;wait_til_gone.sqs _logic = _this select 0 @ choppername distance _logic > TownRadius: this exec "checktown.sqs" exit EDIT: fixed > and added code to get in and out of the loop... Share this post Link to post Share on other sites
johnnyboy 3797 Posted June 28, 2007 Building on TJ72's ideas, you could to this with one script, that loops every second or so. Â Here's the idea, exact code syntax not guaranteed... First you put a marker in each town, and name it the same as the town. <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> #Loop ?(player distance somato) <= 1000: Â hint "Welcome to Somato"; ?(player distance cayo) <= 700: hint "Welcome to Cayo"; ?(player distance carmen) <= 400: hint "Welcome to Cayo"; ...etc... ~1 goto "Loop" Note that you make the distance from town center marker larger or smaller depending on town. Another alternative to placing a marker in each town, would be to build a list of town global variables in your init.sqs that holds the position of the center of each town. Â Here's how this code would look in your init.sqs: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> gSomato = [x,y,0]; gCayo = [x,y,0]; gCarmen = [x,y,0]; Obviously, you need to specify x,y for each of the towns. Then you would modify the previous script to compare against these global variables. Â It would be some work to collect the x,y coordinates, but once you have done this, you have a library of town coordinates that may be useful for other purposes, and useful to the whole community. Â If you do this, please post the list of town coordinates. Â It would be even better to put all "town properties" (name, center position, radius) into a single global Town Library array: Library array in INIT.SQS: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> ; Library array of Town Name, Town Center Position, and Town radius: gTownLibrary = [ ["Cayo", [x,y,0], 1000], ["Somato", [x,y,0], 700], ["Carmen", [x,y,0], 400] ]; Note that gTownLibrary is now basically a "table" of town records, where each town record has 3 attributes: Name, Center Position, Radius. You would then change your distance check script to test player distance to each town in the array using a loop. Â This script becomes nice and short, and requires no town maintenance. Â Town maintenance is all done in the Town Library Array. <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> #Loop {?(player distance ((gTownLibrary select _x) select 1)) <= ((gTownLibrary select _x) select 2): hint format ["Welcome to %1", (gTownLibrary select _x) select 0]} forEach gTownLibrary; ~1 goto "Loop" The beauty of the above code is it is now "table driven" rather than "hardcoded" for each town. Â In English, the above code is saying: Loop through each town in the Global Town Array, and display "Welcome to <town name>" if the distance from the player to the Town Center is less than the Town radius. Repeat this loop every second. Sorry for the long post...the idea evolved as I was typing... Share this post Link to post Share on other sites
UNN 0 Posted June 28, 2007 Quote[/b] ]Is there a dynamic or generic way to get town names? Yes, use the config commands. This will give you an array of all towns and their positions on the current map: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_Towns=[]; _CfgTowns=(configFile >> "CfgWorlds" >> WorldName >> "Names"); For "_i" from 0 to ((Count _CfgTowns)-1) Do     {     _CfgPath=_CfgTowns Select _i;     _Towns Set [_i,[GetText (_CfgPath >> "name"),GetArray (_CfgPath >> "position")]];     }; Hint Format ["Towns %1",_Towns]; From that you can either setup triggers using the CreateTrigger command or write a script to do a distance check. Share this post Link to post Share on other sites
johnnyboy 3797 Posted June 28, 2007 That is sweet! Â No tiresome library building required. I have a question about this line though: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_CfgTowns=(configFile >> "CfgWorlds" >> WorldName >> "Names"); I'm assuming that this searches the object hierarchy in the configFile under CfgWorlds to return only Town names. Is that right? Are towns the next child below "CfgWorlds"? Please explain how that works. Share this post Link to post Share on other sites
Taurus 20 Posted June 28, 2007 Thanks UNN! That was EXACTLY what I was looking for! (thanks to JohnnyBoy and TJ72 too ofc) <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_cfgPath = _cfgTowns Select _i; Returns SARA_TOWNNAME HILL_HILLNAME FOREST_FORESTNAME I would like to "translate" SARA_ to "TOWN" HILL to "HILL" etc. And adding a third element in _towns array "HILL", "TOWN" and so on. But I can't understand how this would be done. find only works for arrays, and I can not understand how to "cast" the string _cfgPath into an Array object. Or maybe if there are another element such as "type" see: _CfgPath >> "position" I dunno how to extract the bin file into something that I can read so JohnnyBoy Yes it seems its the hierarchy in the bin-file But as mentioned above, _CfgTowns has all locations with a name. [edit] This is what I got so far (hints locations as you fly/drive past them) http://files.filefront.com//;7910117;;/ [edit2] Some other thing I found out is that some of the town names are empty. Which I had to check with "if(_townName != "")then{addTriggerstuff}" (all found in the script if you de-pbo my mission) Share this post Link to post Share on other sites
UNN 0 Posted June 28, 2007 Quote[/b] ]That is sweet!  No tiresome library building required. Yeah, it is a neat solution. Thanks to someone on the staff at BIS no doubt. Quote[/b] ]I'm assuming that this searches the object hierarchy in the configFile under CfgWorlds to return only Town names.  Is that right? Yes, they are direct, child, class names to cfgWorlds. You could do the same with class SecondryAirports or class clutter e.t.c I particularly like the ability to store the config paths as a variable. I ripped that out of missions.pbo. Which is straight from the horse’s mouth...so to speak Would be nice to see more examples of that ilk. Share this post Link to post Share on other sites
Taurus 20 Posted June 28, 2007 UNN Is it possible to determine what type which is returned? Like, hill, town, wine yard, forest? Share this post Link to post Share on other sites
UNN 0 Posted June 29, 2007 Quote[/b] ]Is it possible to determine what type which is returned? Yeah, to a certain degree. Here is a filtered list of just the populated areas. Unpbo sara.pbo to see what other types there are. <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_Towns=[]; _TownTypes=["NameCityCapital","NameCity","NameVillage"]; _CfgTowns=(configFile >> "CfgWorlds" >> WorldName >> "Names"); For "_i" from 0 to ((Count _CfgTowns)-1) Do     {     _CfgPath=_CfgTowns Select _i;         If ((GetText (_CfgPath >> "type")) in _TownTypes) then         {         _Towns=_Towns+[[GetText (_CfgPath >> "name"),GetArray (_CfgPath >> "position")]];         };     }; Hint Format ["Towns %1",_Towns]; @The_Tarus Sorry I missed your previous post. Quote[/b] ]ReturnsSARA_TOWNNAME HILL_HILLNAME FOREST_FORESTNAME I would like to "translate" SARA_ to "TOWN" HILL to "HILL" etc. The first bit: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_cfgPath = _cfgTowns Select _i; Just returns a pointer to the class name. After that you need to pull out the different properties associated with that class, like name and type e.t.c using: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">GetText (_CfgPath >> "type") There are types for "Hill" and "VegetationVineyard". The entries with empty names use type "ViewPoint". To add those to your array, just change the script to read: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_TownTypes=["NameCityCapital","NameCity","NameVillage","Hill"]; And: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_Towns=_Towns+[[GetText (_CfgPath >> "name"),GetArray (_CfgPath >> "position"),GetText (_CfgPath >> "type")]]; Quote[/b] ]I dunno how to extract the bin file into something that I can read so Once you have unpbo'ed the addon use unRap.exe to convert the config to a text file. Share this post Link to post Share on other sites
Taurus 20 Posted June 30, 2007 Excellent!! for some reason I can not get <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">switch (_type) do { case "NAMEVILLAGE": { //Do stuff }; }; To work on the "type" returned I tried with format and everything, but I had to use <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">if(_type == "NAMEVILLAGE")then{}; instead. Here is the result! http://files.filefront.com//;7924465;;/ Share this post Link to post Share on other sites