Jump to content


  • Content Count

  • Joined

  • Last visited

  • Medals

Community Reputation

104 Excellent


About Muzzleflash

  • Rank
    First Sergeant


  • Interests
    Little of everything

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. The problem with setObjectTextureGlobal and textures placed in the mission folder is that: you pass it a relative path to the texture in the mission folder; however, it will resolve to an absolute path, and then that path is attempted to be applied on other machines, which will not work since that absolute path is (likely) not valid on other machines. Instead, what I do, is apply the local version of setObjectTexture on all machines. If the billboard texture is never supposed to change, then you can get away with just doing this in the init lines: this setObjectTexture [0,"texture.paa"];
  2. It can be used in SP to use a texture placed with the mission. That is probably old stuff from before I finished converting BIS_fnc_setUnitInsignia to fully mission-MP compatible. I have removed it now since it is no longer needed.
  3. This is old stuff, from a modified BIS_fnc_setUnitInsignia, uploaded as is it with a few comments. It has been used successfully for many sessions so should work unless I made a screwup with putting it up now. It is missing the actual insignia texture used, and a mission.sqm for it to be a self-contained example. You can download the zip on the button to the right. Note my version is local by default and there is a global function too. https://gist.github.com/senevoldsen/3dd0f7171fc1080cf674a29569d1c5ee Forgot to write, this is only the script-solution part. To Virtual Arsenal to work you will probably have to do more changes to that. In that case the simplest solution is probably to make tiny addon with the insignia.
  4. I don't remember the circumstances leading to it, but I am the belief that setVariable does not work fully with that kind of objects. To the best of my memory, something about buildings/map objects not having identity the same manner as other vehicles. Buildings might be streamed in/out as you travel the map. I am guessing if you save/load the same might happen. Have you tried spawning the building instead and repeating the experiment?
  5. Muzzleflash

    Add all player UIDs to array

    You want to use 'apply' instead of 'foreach'. And you then need to switch the order.
  6. Muzzleflash

    Which Release Licence?

    While they might use BI tools "under the hood", you are not using BI tools directly, in fact you are "just" using Arma 3 via. the EULA I guess. Of course this raises the question whether you have a license to do anything with a mission file .sqm at all - I guess it enters the same category as whether you may legally sell a save game.
  7. UPDATE: You might just want to wait it out. See .kju post below. Path finding is really one of those things you want the engine to do the grunt work of. --------------------------------------------------------------------- Graph problems are a vast area with plenty of theoretical and practical considerations. For your basic problem, there are many simple algorithms to find a path between two nodes. You might be able to do all you want using just a single algorithm. Define "anywhere else". Search algorithms that work for enclosed areas are often not so good for open areas and vica versa. So I would advise the following considerations: - I assume you are running this in SQF, so you might avoid doing calculations that could be done ahead of time. - How many nodes are there? What is the typical and the max? - I am guessing these nodes are particular to a specific building model/class And regarding your bonus challenge: you may want to relax that it is the shortest, and rather just have it be one of the shorter but not necessarily the best. This depends again on how many nodes, but the problem is known as the Travelling salesman problem which is well studied. Basically for around ~30 nodes it is just not practical anymore. If you have say, at most 20 nodes, you might just want to compute the best way to get to *any* destination, e.g. where to go next. For 20 nodes you just have to fill an 20*19/2 = 190 element array (a matrix). So you are at node #5 and want to get to #17. You look up in the array for #5 and destination #17 and it says #9. You go to #9, and look up again for #17 and it says #2. You go to #2, and it says #17, you go to #17. Congratulations you have arrived at your destination. The benefits of this approach is you don't really need to "compute" in SQF, you just look up so it is much faster. Though this approach does not scale so well 30 nodes might be doable too, but 100 nodes will require almost ~5000 elements in the array (this might actually also be doable....). If you only have a few nodes you are starting/ending from, and most are just "intermediates", then you can use an even smaller array. For you bonus challenge, I humbly suggest using a minimum spanning tree instead and walking around that instead. Some time ago for fun I tried that approach to create patrolling waypoints. In this example, the outer blue circle is the area to be observed, the red circles are "subtasks" making up teh area. The black dots, which are the waypoints, are placed first in each of the red circled areas, and indicates places with decent vegetation/concealment the problem should go to and observe from. Then the green lines indicate the minimum spanning tree, to reduce travelling times. https://imgur.com/a/9CBkg
  8. Muzzleflash

    Match numbers place increase

    So the inputs are Min and Max. Say the "steps" move us along the X-axis, and on the Y-axis we have the value. Using just a linear function where the Y value is the element position in the output: "Y = StepSize * X + Min" where X is the same as Index in this case, it might take a long time (many Index) to reach Y >= Max as you already observed. So rather than that, let us use a polynomial (second-degree) and drop the step size for now and just consider this perhaps: "Y = X^1.8" (this looks like this, https://www.wolframalpha.com/input/?i=y+%3D+x^1.8+where+0+<+x+<%3D+1 ). The thing we are looking for here is whether the "curve" itself looks right. The normal linear is "Y = X^1". This one makes it rise much slower in the start and much faster in the end; notice the midpoint for X=0.5 is only about Y=0.3. So half of the values would be in the first 30%. By increasing, e.g. to ^3, half would be in lower 10% of the value. To use this we just need to map our index to 0-1 and map the output to the proper value. So how many values? Well you can easily pick that yourself: NNJ_fnc_Populate = { params ["_min", "_max", "_count", ["_pow", 1.8]]; private _result = []; // We iterate from 0 to count-1 and need to divide by count-1 anyway private _countMinusOne = _count - 1; private _maxMinDiff = _max - _min; for "_i" from 0 to _countMinusOne do { // Normalize the X value to between 0 and 1 (inclusive) private _xVal = _i / _countMinusOne; // Compute the normalized Y-value private _yVal = _xVal ^ _pow; // Map the _yVal back to the desired range private _value = _min + _maxMinDiff * _yVal; _result pushBack _value; }; _result }; // So if you want a 1000 values. private _min = 0; private _max = 5000000; private _valuesA = [_min, _max, 1000] call NNJ_fnc_Populate; // Or you want 3000 values distributed but rounded, and using ^1.2 // Note, if you round with a power too multiple elements in the beginning may be the same, e.g. zeroes and ones. private _valuesB = ([_min, _max, 1000, 1.2] call NNJ_fnc_Populate) apply {round _x};
  9. Seems like this thread went off the rails, but it can still get back on tracks.
  10. Muzzleflash

    Credits Not As Intended

    I think the problem is that valign only works in some containing box. You assume that cutText operate on the entire screen as that box, but I think it just creates the box with the top in the center and then the bottom whatever height your text have. If you look at the example here at the bottom https://community.bistudio.com/wiki/Structured_Text#SQF_Code_Examples you can see they wrap size=1 text inside size=3 to demonstrate - that way the "box" will be at least 3 units large. Though my guess is that you cannot do that since cutText will still place the "main box" center and below. So my bet is you will need to use https://community.bistudio.com/wiki/cutRsc or some other command.
  11. Have you checked what the view distance on the server is? Some mods or scripts reduce this - have often occasionally seen something like if: (isDedicated) then { setViewDistance 500; }; being run from scripts in the mission.
  12. You could go with a custom debriefing section https://community.bistudio.com/wiki/Debriefing#Custom_Sections . I have used this to show lots of miscellaneous information, like distance travelled on foot, or in vehicle, amount of time spent talking on task force radio, etc.. But I would try this first addPlayerScores if you can settle with just fixing the kill statistics.
  13. Muzzleflash

    Insignia problem

    Since the original BIS function does not work in MP with non-addon based insignia image, I have modified them for proper MP/JIP. I have split them into a local and a global function: /* MF_fnc_setUnitInsignia Argument: Global Effect: Local Description: Sets unit insignia (e.g., shoulder insignia on soldiers) Parameter(s): 0: OBJECT - unit 1: STRING - CfgUnitInsignia class. Use an empty string to remove current insignia. Returns: BOOL - true if insignia was set */ #define DEFAULT_MATERIAL "\a3\data_f\default.rvmat" #define DEFAULT_TEXTURE "#(rgb,8,8,3)color(0,0,0,0)" params ["_unit", "_class", ["_forceLoad", false]]; private _isRefresh = _class isEqualTo "REFRESH"; if (_isRefresh) then { _class = _unit getVariable ["MF_fnc_setUnitInsignia_class", ""]; }; // --- load texture from config.cpp or description.ext private _cfgInsignia = [["CfgUnitInsignia", _class], configNull] call BIS_fnc_loadClass; // --- check if insignia exists if (configName _cfgInsignia != _class) exitWith { [ "'%1' is not found in CfgUnitInsignia. Available classes: %2", _class, ("true" configClasses (configFile >> "CfgUnitInsignia") apply {configName _x}) + ("true" configClasses (missionConfigFile >> "CfgUnitInsignia") apply {configName _x}) + ("true" configClasses (campaignConfigFile >> "CfgUnitInsignia") apply {configName _x}) ] call BIS_fnc_error; false }; private _set = false; // --- find insignia index in hidden textures { if (_x == "insignia") exitWith { // --- make it safe in scheduled isNil { // --- set insignia if not set if (_isRefresh or {_forceLoad} or {(_unit getVariable ["MF_fnc_setUnitInsignia_class", ""]) != _class}) then { _unit setVariable ["MF_fnc_setUnitInsignia_class", [_class, nil] select (_class isEqualTo ""), false]; _unit setObjectMaterial [_forEachIndex, getText (_cfgInsignia >> "material") call {[_this, DEFAULT_MATERIAL] select (_this isEqualTo "")}]; _unit setObjectTexture [_forEachIndex, getText (_cfgInsignia >> "texture") call {[_this, DEFAULT_TEXTURE] select (_this isEqualTo "")}]; _set = true; }; }; }; } forEach getArray (configFile >> "CfgVehicles" >> getText (configFile >> "CfgWeapons" >> uniform _unit >> "ItemInfo" >> "uniformClass") >> "hiddenSelections"); _set The global function: /* Argument: Global Effect: Global Description: Sets unit insignia (e.g., shoulder insignia on soldiers) Parameter(s): 0: OBJECT - unit 1: STRING - CfgUnitInsignia class. Use an empty string to remove current insignia. Returns: BOOL - true if insignia was set */ params ["_unit", "_class", ["_force", true]]; if (_class isEqualTo "REFRESH") then { _class = _unit getVariable ["MF_fnc_setUnitInsignia_class", ""]; }; // For remotes [_unit, _class, _force] remoteExecCall ["MF_fnc_SetUnitInsignia", -clientOwner]; // For JIPs _unit setVariable ["MF_fnc_setUnitInsignia_class", _class, true]; // We run it locally manually to get return value. // using REFRESH here after setVariable to ensure _force is respected. [_unit, "REFRESH", _force] call MF_fnc_SetUnitInsignia; To ensure proper loading for JIPs and also for player changing uniform, I run the following post-init: // Updates client insignias from broadcast data { private _insignia = _x getVariable ["MF_fnc_setUnitInsignia_class", ""]; if (not (_insignia isEqualTo "")) then { [_x, _insignia, true] call MF_fnc_setUnitInsignia; }; } forEach allUnits; // For simplicity only handle local player changing loadouts. E.g. not AI's that has later been changed by scripting. if (hasInterface) then { [] spawn { waitUntil {sleep 0.1; local player}; MF_fnc_setUnitInsignia_lastUniform = uniformContainer player; player addEventHandler ["InventoryClosed", { params ["_unit", "_targetContainer"]; private _curUniform = uniformContainer _unit; if (_curUniform != MF_fnc_setUnitInsignia_lastUniform) then { MF_fnc_setUnitInsignia_lastUniform = _curUniform; if (not (isNull _curUniform)) then { [_unit, "REFRESH", true] call MF_fnc_setUnitInsigniaGlobal; }; }; }]; }; }; The corresponding CfgFunction entry is: class CfgFunctions { class MF_Insignia { tag = "MF"; class Insignia { file = "functions"; class setUnitInsignia {}; class UnitInsignia_PostInit { postInit = 1; }; class setUnitInsigniaGlobal {}; }; }; };
  14. Muzzleflash

    Private variable in trigger?

    When you create the trigger store the bomber on it (using setVariable), and I recommend you move your activation code to a separate script: _trgr_bomber_1 setVariable ["Spatsiba_TriggerMan", _bomber, true]; _trgr_bomber_1 setTriggerStatements ["this", "[thisTrigger] execVM 'activateTriggerman.sqf';", ""]; Then you move the activation code to that script instead, and here you can the associated triggerman from the trigger. // This is activateTriggerMan.sqf params ["_trigger"]; private _bomber = _trigger getVariable "Spatsiba_TriggerMan"; if (not alive _bomber) exitWith {}; private _bomberGroup = group _bomber; hint 'trigger start'; _bomber selectWeapon '_bomber_weapon'; _bomber enableAI 'MOVE'; _bomber setUnitPos 'AUTO'; _bomberGroup setbehaviour 'COMBAT'; _bomber setCaptive false;
  15. Try with BattlEye turned off, it block non-whitelisted extensions (you can see if it did this in the launcher when starting).