Jump to content
madrussian

Buildings that are actually Terrain Objects

Recommended Posts

I'm developing an AI system, and need to get the types of various buildings.  This is usually trivial, as one can use the nearestObjects or cursorTarget commands.

 

But on Dingor Island, turns out certain buildings are actually (apparently) technically terrain objects.  There are at least two of these I know about: the large apartment style buildings (which come in 3 different heights) and these small wooden huts.  For my AI system to work properly, these terrain object buildings are no good, and I need regular buildings instead.  The main problem is, that typeOf on these terrain obj buildings doesn't work (returns empty strings).

 

Thankfully I've succeeded in detecting and swapping out the large apartment buildings, like this:

  1. Detect all terrain objects via nearestTerrainObjects (within the desired area).
  2. Get the string of each of those objects.  (Because, again typeOf won't work on these terrain objects)
  3. Get all the terrain objs within that set where substring "ibrpanenak" is present (which I guess "panenak" is Czech for apartment).
  4. Hide the offending buildings via hideObjectGlobal, and place in usable (i.e. normal, non terrain obj) building that's essentially the same thing with a different texture, in this case building type "Land_Panelak1_Grey".

So far so good.  But then unfortunately, I tried this same method for the little wooden huts, and turns out the string of these particular terrain obj buildings don't return anything useful (only substring "house", which of course is the base class for most buildings).

 

Couple questions:

  1. Anyone know where terrain objs are defined in the config?  (I suspect cfgVehicles, but have not been able to prove this, seeing as I can't actually get the types for these particular "building terrain objects".)
  2. If these "building terrain objects" are actually defined within cfgVehicles, that means they must have a type.  How can I get their type?

OK, that's it.  I welcome any and all help, even with simple things I may have missed. 🙂

Share this post


Link to post
Share on other sites

May I suggest to use the MGI advanced module "touch of class" which enable you to find all type (if any) or model (p3d) of any object on map?

You can load this addon and unload it (or not) . The module itself doesn't matter. It's just a tool for mission maker (until you change some house by another object/house, but it's another aim: see your pt4. Then you need to keep the module).

Some objects have no type, but you can find the model.

You will see also if there are some positions in buildings/houses (blue: yes, red: none)

Then, as example:

nearestTerrainObjects [player,[],20] select {(getModelInfo _x #0) == "bilboard_presidente.p3d"}

will return a non-class object, model  billboard_presidente.p3d, if any close to player.

 

  • Thanks 1

Share this post


Link to post
Share on other sites

What I use for a mission I'm working on to filter specific terrain objects is the (getModelInfo _object # 0) command. Something like this:
 

_objects=nearestTerrainObjects [_pos, ["TREE","SMALL TREE"], 200 ] select {(getModelInfo _x#0) in ["p_papaver_ep1.p3d","p_fiberplant_ep1.p3d"]};

The above code will make _objects return a list of terrain objects that are only weed / poppy plants (Takistan). The in command is case-sensitive, but getModelInfo seems to always lower-case the strings it returns, which is good. Make sure the array of strings you're comparing is also lower-case and it'll work fine. Not sure if your method or mine is faster, but can't hurt to know.

  • Thanks 1

Share this post


Link to post
Share on other sites
3 hours ago, pierremgi said:

May I suggest to use the MGI advanced module "touch of class" which enable you to find all type (if any) or model (p3d) of any object on map?

You can load this addon and unload it (or not) . The module itself doesn't matter. It's just a tool for what you want (until you change some house by another object, but it's another aim).

Some objects have no type, but you can find the model.

You will see also if there are some positions in buildings/houses (blue: yes, red: none)

 

Wow, that is mighty useful indeed!  (If anyone hasn't seen his video, please do click on that link.)  Sounds like your tool is just the thing, to be able to tell immediately whether these huts have a type or not.

 

3 hours ago, phronk said:

What I use for a mission I'm working on to filter specific terrain objects is the (getModelInfo _object # 0) command. Something like this:
 

_objects=nearestTerrainObjects [_pos, ["TREE","SMALL TREE"], 200 ] select {(getModelInfo _x#0) in ["p_papaver_ep1.p3d","p_fiberplant_ep1.p3d"]};

The above code will make _objects return a list of terrain objects that are only weed / poppy plants (Takistan). The in command is case-sensitive, but getModelInfo seems to always lower-case the strings it returns, which is good. Make sure the array of strings you're comparing is also lower-case and it'll work fine. Not sure if your method or mine is faster, but can't hurt to know.

 

Super handy advise, thanks!

 

Ok so, if I ever want to determine via script whether a terrain obj has a type or not, sounds like I'd want to:

  • Use getModelInfo on the terrain obj to get the model string, and then perhaps query cfgVehicles for types using that model (via some property, probably model or similar)?  And if query comes up empty, that should tell me that no cfgVehicles types use that model?

^ Does this sound reasonable, or is there a simpler way to do this (again via script)?

Share this post


Link to post
Share on other sites

You can do a switch structure which looks through an array of strings (Strings of classnames and .p3d model names) sorta like this maybe:

 

 

_nearestObjs=nearestObjects[player,["House_F"],200]; //Collect nearestObjects, likely all will be able to return a typeOf

 

_nearestTObjs=nearestTerrainObjects[player,["HIDE"],200]; //Collect nearestTerrainObjects, needs getModelInfo to determine what it is

 

_objects=_nearestObjs+[-nearestTObjs]; //Combine list of objects

 

_objectString=selectRandom _objects; //Select a random object from the array; definitely not how YOU will select objects, more likely though a forEach and/or select


if(isSimpleObject _objectString)then{_objectString=getModelInfo _objectString#0}else{_objectString=toLowerANSI(typeOf _objectString)}; //Identifies the object whether it needs to use typeOf or getModelInfo

_myArrayOfStringsToPull=["land_house_01_f","land_shed_01_f","chairwood.p3d"]; //Just a brief array of classnames to look for

 

if(!(_objectString in _myArrayOfStringsToPull))exitWith{}; //If _objectString doesn't match one of the strings in the array above, exit script.

 

//The switch structure below sort of how I do my furniture script if you wanted a specific function called for a specific house classname, or whatever
switch(_objectString)do{

case"land_house_01_f":{ hint"This is a house!" };

case"land_shed_01_f":{ hint"This is a shed!" };
case"chairwood.p3d":{ hint"This is a simpleObject chair, pulled with getModelInfo! Yay!" };
};

//////////


Definitely not optimized the way it's coded above, but gives you a general idea how you can filter for both nearestObjects and nearestTerrainObjects. Keep in mind that nearestTerrainObjects is heavier than nearestObjects, so use it as little as possible. getModelInfo is also slower than typeOf (Likely because it returns more information and toLower's the strings). It may even be possible to just str the nearestTerrainObject and filter for the model, but I'm not sure if that works. If so, that'd be faster than getModelInfo.

  • Thanks 1

Share this post


Link to post
Share on other sites

If you want to replace ibrpanelak.p3d and ibrpanelak2.p3d objects (no classes) by a script, you can place your trigger (server only), condition TRUE,

and in on activation field:

{

  _dir= getDir _x;

  _pos = getPosASL _x;

  _x hideObjectGlobal TRUE;

  _new = createVehicle ["Land_Panelak1_Grey", ASLToAGL _pos,[],0,"can_collide"];

  _new setDir _dir;

} foreach (nearestTerrainObjects [getPos thisTrigger,[],200] select {getModelInfo _x #0 in ["ibrpanelak.p3d","ibrpanelak2.p3d"]})

 

 

Share this post


Link to post
Share on other sites
13 minutes ago, pierremgi said:

If you want to replace panelak and panelak2.p3d objects (no classes) by a script, you can place your trigger (server only), condition TRUE,

and in on activation field:

{

  _dir= getDir _x;

  _pos = getPosASL _x;

  _x hideObjectGlobal TRUE;

  _new = createVehicle ["Land_Panelak1_Grey", ASLToAGL _pos,[],0,"can_collide"];

  _new setDir _dir;

} foreach (nearestTerrainObjects [getPos thisTrigger,[],200] select {getModelInfo _x #0 in ["ibrpanelak.p3d","ibrpanelak2.p3d"]})

 

Thanks, yes that's pretty much exactly what I'm doing for those panelaks (small, medium and large).  With those, I happened to get lucky because even though panelak.p3d objs have no type name, I knew of the equivalent building(s) type to replace them with.  (I was using str command instead of getModelInfo in my method though.  Thanks to you guys, I know how to use getModelInfo effectively now too.)

 

It's those wooden huts I'm having trouble with.  If we assume for a moment that they have no type (which I'll confirm soon), the problem is I know of no equivalent cfgVehicles type to replace them with.  (If your curious about which huts I'm talking about, they are on Dingor Island at the Melana Resort, which is along the NE corner of the big airport to the south, which itself is just east of Calamar.)

Share this post


Link to post
Share on other sites

I did a brief test because it got me curious, and found out that checking for a match via in (str _x) is slightly faster than in (getModelInfo _x)#0

 

Screenshots to prove since seeing is believing:

https://imgur.com/rujpIkH

(Str = 0.0057ms --- getModelInfo = 0.0059ms)

Share this post


Link to post
Share on other sites
27 minutes ago, phronk said:

You can do a switch structure which looks through an array of strings (Strings of classnames and .p3d model names) sorta like this maybe:

...

 

Wow thanks, that's quite a detailed response!  Looks like it will probably work.  Btw- Not necessarily going for speed for this building replacement routine.  It's more for the demo mission, just to get the right buildings in place (and only happening in a smaller area).  But yes, definitely nice to know which is quicker. 🙂

Share this post


Link to post
Share on other sites

You can try to replace "house.p3d" by "Land_Hut01" ... to 06. I don't know why you want to replace these huts.

Share this post


Link to post
Share on other sites
51 minutes ago, pierremgi said:

You can try to replace "house.p3d" by "Land_Hut01" ... to 06.

 

Thanks, I just checked and "Land_Hut01" (... to 06) use different models than our "house.p3d" hut.  Which is fine, but the "house.p3d" huts in Melana Resort are special, because they offer 360 degree defense (via the windows & door on all sides).

 

56 minutes ago, pierremgi said:

I don't know why you want to replace these huts.

 

My AI system uses buildings, and every building needs a type in order to be used.  And I was trying to make sure all 360 degree defense buildings can be used.  I suppose I could re-write a good bit of my code so it can handle "terrain object" (aka type-less) buildings too.  But probably not worth it for a silly wooden hut.  On the other hand, if I start finding a whole bunch of these "terrain object" buildings then will have to rethink it.  And btw - There are a ton of panelaks on Dingor, so this "terrain object building" phenomenon might be more prevalent than we might otherwise suspect.

 

In the mean time, will do a quick query sooner or later and see if any cfgVehicles buildings use that "house.p3d" hut model (again for it's nice 360 degree defense), and if possible auto-replace like with those panelaks.  Thanks for info & ideas guys!

 

Share this post


Link to post
Share on other sites

Instead of type you could try using the new command namedProperties, it returns stuff like [["class","house"],["map","house"],["prefershadowvolume","0"]] and for example the property map exists on all terrain objects that are shown on the map.
:shrug:

Oh, and didn't spot an answer to one of your questions; terrain objects don't have type because they are not defined in any config.

  • Like 1

Share this post


Link to post
Share on other sites

Pretty sure it's gonna be in the main branch eventually though.

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

×