Jump to content

Recommended Posts

3 hours ago, killzone_kid said:

 

You can always count building positions:
 


_floors = []; 
{
  _floors pushBackUnique round (_x select 2);
} 
forEach (cursorObject buildingPos -1); 
hint str count _floors;

returns 6 for offices

 

offices have a couple bugged  building positions above the rooftop, the ones on the edge behind the ladder

Share this post


Link to post
Share on other sites
5 hours ago, fn_Quiksilver said:

 

offices have a couple bugged  building positions above the rooftop, the ones on the edge behind the ladder

 

has this been reported?

Share this post


Link to post
Share on other sites
14 hours ago, killzone_kid said:

 

has this been reported?

 

i doubt it, ill create a report later

 

edit:

 

looks like there actually isn't an issue in 1.67, its either been addressed or its instead an issue with my garrison script.

 

code i used to check in the editor:

 

QS_drawBuildingPositions = addMissionEventHandler [
    'Draw3D',
    {
        if (!isNull (nearestBuilding player)) then {
            if (!(((nearestBuilding player) buildingPos -1) isEqualTo [])) then {
                {
                    
                    drawIcon3D [
                        '\a3\ui_f\data\igui\cfg\radar\radar_ca.paa',
                        [1,1,1,1],
                        _x,
                        0.75,
                        0.75,
                        0,
                        (format ['%1',_forEachIndex])
                    ];
                } forEach ((nearestBuilding player) buildingPos -1);
            };
        };
    }
];

Share this post


Link to post
Share on other sites

Dedmen found something pretty interesting about eventhandlers anyone should keep in mind when thinking about performance.

It appears that the game stores the event code passed by all addXEventHandler SQF commands as string internally and it has to recompile that to executable SQF CODE every time the eventhandler is executed. This means that there is unexpected and significant overhead especially for long functions.

 

It has been confirmed for addEventHandler, addMissionEventHandler, ctrlAddEventHandler and displayAddEventHandler and is therefore probably true for all other SQF commands similar to that as well. It does not matter if you use the STRING vs. CODE syntax that some of these commands support for backwards compatibility. The CODE seems to be stored as string internally regardless.

It does not affect stuff like BIS_fnc_addStackedEventHandler or BIS_fnc_addScriptedEventHandler (or any similar function in CBA for that matter), because those generally already store the compiled code in variables, which do not have to be recompiled ever again.

 

Used test case / proof:

 

Definition of "TestingFunction" (The function itself has no meaning. It's just something to put stress on the STRING -> CODE compiler.):

Spoiler

 


TestingFunction = {
    if (true) exitWith {};
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
    {call { call {call{}}}} forEach variableStuff;
    missionNamespace getVariable ["",{call{call { call {call{}}}} forEach variableStuff;}];
};

 

 

 

 

for [{_i=0}, {_i<1000}, {_i=_i+1}] do {addMissionEventHandler ["EachFrame", TestingFunction];}; //~760ms per frame
for [{_i=0}, {_i<1000}, {_i=_i+1}] do {addMissionEventHandler ["EachFrame", {call TestingFunction}];}; // ~47ms per frame

To clarify, the numbers are for executing the eventhandler, not for adding it. It does not matter if the variable is a local or a global one.

 

The solution can be seen in the second test. While there is one additional "call" command, which also means, that there is one additional scope, the function that the game stores as string and which has to be recompiled for every execution is very short. The complexity of compiling strings to executable code seems to be linear to the length of the string generally speaking, which means that short strings like "call TestingFunction" are compiled pretty fast, while compiling the whole content of 'TestingFunction' would be very slow.

 

While this probably doesn't matter all that much for eventhandlers like "init", "killed" or "respawn"; it's a very big cost for eventhandlers that are executed very frequently or even multiple times in a single frame like "EachFrame", "Draw", "handleDamage", "fired", "firedNear" etc.

 

tl;dr

Always use:

addEventHandler ["whatever", {call My_fnc}];

instead of:

addEventHandler ["whatever", My_fnc];

 

Edit:

Feedback tracker report: https://feedback.bistudio.com/T123355

  • Like 13

Share this post


Link to post
Share on other sites
On 2/13/2017 at 7:27 AM, killzone_kid said:


From v1.69.140138 you would be able to get multiple intersections with the same object https://community.bistudio.com/wiki/lineIntersectsSurfaces

 

_p0 = positionCameraToWorld [0, 0, 0];
_p1 = positionCameraToWorld [0, 0, 50];
lineIntersectsSurfaces [_p0, _p1, player, objNull, true, 1, "GEOM"];

Will throw script error OR sometimes hard crash game. [Version: 1.69.140502]

Error position: <lineIntersectsSurfaces [_p0, _p1, player>
Error Type Any, expected Bool

Seems to be related to the LOD1 ("GEOM") param, either without or with 2 LODs it seems to work.

 

  • Like 2

Share this post


Link to post
Share on other sites
20 minutes ago, pabstmirror said:

Seems to be related to the LOD1 ("GEOM") param


Spot on! Will be fixed ASAP. 

  • Like 1

Share this post


Link to post
Share on other sites
18 hours ago, pabstmirror said:

Will throw script error OR sometimes hard crash game. [Version: 1.69.140502]


Should be fixed since 1.69.140527 and if we're lucky get into RC

Share this post


Link to post
Share on other sites

The new modelToWorldVisualWorld command should be renamed to modelToWorldWorldVisual.

There already is getPosASLVisual for example. This is how you would disect the name:

getPos  - ASL         - Visual
command - height type - render time

So the suffix for the "height-relative-to"-type comes before the "Visual" suffix to indicate using the render scope.

 

What is the reason for naming PosWorld how it is anyway? It's the same as ASL with z=0 being the model center instead of the lowest point in the LandContact LOD. It should've been named Center or ASLCenter imo.

Share this post


Link to post
Share on other sites

parseSimpleArray can be used to deserialize strings, numbers and booleans as well as multidimensional arrays containing any of these using this function:

private _fnc_parseAny = {
    parseSimpleArray format ["[%1]", _this] select 0
};

str -1 call _fnc_parseAny // -1
str "teststring" call _fnc_parseAny // "teststring"
str [-1,"testarray"] call _fnc_parseAny // [-1,"testarray"]
str false call _fnc_parseAny // false

This is very handy, but raises the question why parseSimpleArray was made to handle stringified arrays only in the first place. Seems counter-intuitive to me.

Share this post


Link to post
Share on other sites

The short function I posted can handle non-array numbers, strings and booleans as well. Why would it have to be limited to arrays?

Share this post


Link to post
Share on other sites
15 minutes ago, commy2 said:

The short function I posted can handle non-array numbers, strings and booleans as well. Why would it have to be limited to arrays?

 

Because it was designed to be used with extensions, so that you could save array and load array fast and secure. Not sure why would you want to use it for anything else? Numbers you can parse with parseNumber, strings you don't need to parse and booleans, well, you can switch to 1 and 0

Share this post


Link to post
Share on other sites

Hi, I'm looking for a script checking if a unit is spawning inside a block (some are huge) or a blind house (without door  like in Tanoa).

I know the isFlatEmpty command but it has too much limitations in rocky hills or downtown. Too much objects, and furthermore no difference between acceptable houses (with doors) and blind ones (+piers...).

It seems to me important because sometimes you can't end a mission due to a stuck/unreachable enemy unit.

I tested something like:

  {deleteVehicle _x} forEach (units _redGroup select {count lineIntersectsSurfaces [getPosWorld _x, getPosWorld _x vectorAdd [0, 0, 5], _x, objNull, true, 1, "GEOM", "NONE"] >0});

just to delete the units inside something after they spawn.

This could be fine to get some command more consistent which could test such situation without deleting units in enterable buildings. Thanks.

Share this post


Link to post
Share on other sites

Best way is not to spawn blindly, and check for an empty space before hand. If you want units inside buildings, there are many ways to do that too.

Share this post


Link to post
Share on other sites
On 03/03/2017 at 10:29 AM, seba1976 said:

Best way is not to spawn blindly, and check for an empty space before hand. If you want units inside buildings, there are many ways to do that too.

It' not exactly what I suggested. I never spawn blindly and always use isFlatEmpty.

 

Right now, if you're scouting for empty places, isFlatEmpty works with gradient, objects (excluded or not), radius,  water or not.

But some maps, like Tanoa unfortunately, have some huge buildings, where you can spawn units, just because the bounding box is larger than radius,... and you don't want to make a bigger radius because there are plenty of objects in town.

 

IMHO, this could be fine to check if the "isFlatEmpty" position is also a "notInside" one (buildings, large rocks, piers...). Something like my script above but included in this command.

Share this post


Link to post
Share on other sites
5 hours ago, R3vo said:

The new "utils" functionality is awesome, but I am wondering whether there is a proper way to open them from a script file, or is it hardcoded to be used with the debug console?

 

https://community.bistudio.com/wiki/Arma_3_Utilities

 

You can execVM them, the files are in Functions_F/Debug/Utilities

Share this post


Link to post
Share on other sites
5 hours ago, killzone_kid said:

 

You can execVM them, the files are in Functions_F/Debug/Utilities

 

Awesome, thanks!

 

 

Edit: Seems like I can execVM them from anywhere but the Eden Menu Strip. Any idea why?

 

The rpt file looks like this if I execute the moonPhases script from the menu strip once. Same happens with the other 3 scripts.

 

https://www.dropbox.com/s/rhheaget3l7j9i7/arma3_x64_2017-03-07_10-06-43.rpt?dl=0

Share this post


Link to post
Share on other sites
14 minutes ago, killzone_kid said:

Cannot see the image, requires login

 

Stupid Dropbox...just click beside the login request, then you can open it.

 

NVM, use this http://pastebin.com/Hjazt09K

Share this post


Link to post
Share on other sites

Is it just me or isn't there a getter command for allowDamage? Is there a specific reason for that?

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

×