Jump to content

dwringer

Member
  • Content Count

    368
  • Joined

  • Last visited

  • Medals

Posts posted by dwringer


  1. Interesting.

     

    ...however, I can't help but wonder why you don't make use of the functions library there:

    https://community.bistudio.com/wiki/Functions_Library_(Arma_3)

    I'm afraid I don't fully understand the reference, although looking through the functions I have found a couple that would have made string manipulation slightly simpler and probably more efficient.  I must caution that this system is not designed for speed, but simply for power of abstraction.  The chaining of functions can get very deep and is bound to cause problems if abused or used heavily. 

     

    I noted that there is a way to register functions in the game's function library, which I have not done as it is all new to me (I have not been active in the community for a while).  I welcome any specific suggestions on how to handle improvements and optimizations like that, but I am out-of-touch when it comes to standard practices with sqf.  This is also designed and tested only for single-player; if anyone with multiplayer coding experience has advice or concerns I'd be grateful.  I'm not entirely sure how the scripts would interact in such an environment.

     

    Finally, I have added to the class hierarchy including a unit group abstraction that offers a center_pos method (giving the mean position of all units in the group instance).  I will be continuing to work on fleshing out classes but the things in the repository are bound to fluctuate wildly in quality as I continue updating and moving things around.

     

    [Edited for clarity]

     

    If you are wondering why fnc_sorted would be more useful than the BI sort functions, it is because you can use fnc_lambda inline to create a custom comparison function and pass it , and an array of any supporting variables, to the sort and get any ordering you can define.

     

    In any case, I have just finished a couple of methods on a CrewUnitGroup class.  This class keeps unit arrays for various roles (driver, gunner, cargo), and vehicles themselves.  There is a simple "assign" method (remove has not been properly overloaded yet so that functionality is not present) which takes a unit and role and adds it to the corresponding array.  The other method is "board_instant", which loops through vehicles dynamically assigning drivers and gunners, then filling in cargo as space allows.  Hopefully this is a better example of what is possible, and maybe even conceivably useful.

     

    [Edited again for update]


  2. We need a proper implementation from Bohemia imo.

    I have always wondered why they didn't add these features to SQF, and presumed it is because if they are used excessively it can be grossly inefficient.  I remember hearing that they were looking into Java or something, but that somehow doesn't sound very appealing.  

     

    I haven't implemented any complex systems with these classes yet, but the functional tools are already proving their worth in my missions and experiments.  The class system will surely prove invaluable (and has already been helpful) in organizing mission components, inheritance trees among abstract concepts, etc.

     

    Anyway, just wanted to let everyone know I have massively upgraded the documentations (trying to find errors - especially in the dependency listings - is something I don't find to be a very rewarding use of time).  They should be usable, which is all that I want from them, but if you have trouble getting a module to work from the docs just try adding the whole repo to your mission first.  That way you can make sure to have any unlisted dependencies.

     

    The class system has been tested and proven effective with the ObjectRoot and Dictionary classes, which show off the abstraction and inheritance capabilities avaialble.  Some other test/example classes of low quality are also included (these are in the classdef/ folder).


  3. I am probably going to work some parts of this into their own independent modules (they can already be used that way but perhaps the codebase isn't too approachable). But, I wanted to announce a couple of things here:

    If anyone checked out this code after my first post you may have found some show stopping bugs. I have been working extensively on this and everything should be working as intended as of now.

    Most importantly: dynamic classes!
    I've seen a few other class implementations in sqf out there, but none of them were much like this - although I'm sure it is out there somewhere :).  I urge you all to check out the idea and share what you think. Here's an example class definition file to hack into objects' native dictionary capabilities:
    https://github.com/dwringer/a3system/blob/master/classdef/Dictionary.hpp


  4. Hello,
    If anyone would like to see a wide assortment of scripts including some helpful functional programming tools and array manipulation utilities, I have assembled several modules with extremely basic documentation at https://github.com/dwringer/a3system

    You are pretty much on your own with these, especially some of the less documented stuff, but the stuff in "lambda" and "vectools" is pretty well tested so far and helpful in a lot of situations.

    I would be interested to hear if anyone makes any use of some of this.

    Best of luck, and let me know if there are any usage questions or problems identified.

     

    EDIT 2: There is now a class system included that is superficially similar to Python classes.  These can be defined in header files using syntax macros, or created on-the-fly using the right functions.  So far there is an ObjectRoot and Dictionary class, but these are more examples than anything.

    EDIT:

    Fixed a couple of functions - in particular, fnc_sorted was destroying the original array passed to it. There was also a problem with using negative indexing in fnc_subseq which should be fixed now.


  5. I Don't understand the question. Are you referring to the fact that the places where you can realistically build these are very limited. To look any good, you need 11m or less or water depth, yet it needs to be some distance from the shore. The location I used is in the straits between the mainland and Ammolofi bay in the NW of the island.

    Although that does answer a question I had, I think he was referring to the fact that your video is private, and thus we are not able to view it at all :)


  6. I meant in A3, to be honest I've never seen them using those "special" stances, it's rare enough if the lean for me.

    By the way I tested, if we change their animation to one of those stances they succesfully turn around and shoot, I wish they used them without scripting though.

    Sorry, yeah; that I can definitely agree with.. but I can also guarantee they do use the stances now and then. I have a half-assed script that positions units in "advantageous" overwatch positions and from there, occasionally I have seen them use the animations. But, these are locations that were tailored to their AI already, so the results don't replicate well on random positions they tend to end up in :(


  7. Thanks. It was cool to see that they used cover for real and didn't go prone like always.

    The AI has been able to effectively use and shoot from cover since Arma 2, it doesn't require any special scripting; just for their behavior to be set to "Combat" (which happens automatically even when they're in "Aware" when they come under effective fire)


  8. Sounds to me like "ff1grp" is not defined. Check your .rpt file and see if you are getting any specific error messages.

    I would find the leader of your ff1grp, if its in the editor, and make sure his init says "ff1grp = group this", and then (as Na_Palm suggests) put a waituntil{time>0} or something into the above script to make sure the group has initialized before this script gets called.

    If this is running inside a trigger you can just make time>0 part of its condition.

    Forgive me if time>0 isn't the best way (or 100% correct way) to do this ... hopefully this might help


  9. What about those who know all of this?

    Then instead of defining the stuff as a dialog, it needs to be defined as a display under the RscTitles class. I have only played around a little bit with it, but I'll paste the relevant sections of my definitions below that hopefully illustrate the differences.

    class RscTitles {	
    
    class Default 
    {
    	idd = -1;
    	fadein = 0;
    	fadeout = 0;
    	duration = 0;
    };
    
    class TalkDisplay {
     idd = 1988;
     onLoad = "uiNamespace setVariable ['TalkDisplay', _this select 0]";
     fadein = 0;
     fadeout = 0;
     duration = 10e10;
     controlsBackground[] = {};
     objects[] = {};
     controls[] = { RscPicture_1200,
    	 RscFrame_1800,
    	 RscText_1000,
    	 RscFrame_1801,
    	 RscText_1001 };	
    ////////////////////////////////////////////////////////
    // GUI EDITOR OUTPUT START (by dwringer, v1.063, #Zonyjo)
    ////////////////////////////////////////////////////////
    
    class RscPicture_1200: RscPicture
    {
    	idc = 1200;
    	text = "#(argb,256,256,1)r2t(camrender0,1.0)";
    	x = 0.005;
    	y = 0.745;
    	w = 0.25;
    	h = 0.25;
    };
    class RscFrame_1800: RscFrame
    {
    	idc = 1800;
    	x = 0;
    	y = 0.74;
    	w = 0.2625;
    	h = 0.26;
    };
    class RscText_1000: RscText
    {
    	idc = 1000;
    	text = ""; //--- ToDo: Localize;
    	x = 0.2625;
    	y = 0.74;
    	w = 0.7375;
    	h = 0.04;
    	colorBackground[] = { 0.1, 0.1, 0.1, 0.8 }; 
            colorText[] = { 1, 1, 1, 1 }; 
    };
    class RscFrame_1801: RscFrame
    {
    	idc = 1801;
    	x = 0.2625;
    	y = 0.78;
    	w = 0.7375;
    	h = 0.22;
    };
    class RscText_1001: RscText
    {
    	idc = 1001;
    	text = ""; //--- ToDo: Localize;
    	x = 0.2625;
    	y = 0.78;
    	w = 0.7375;
    	h = 0.22;
    	colorBackground[] = { 0.1, 0.1, 0.1, 0.6 }; 
            colorText[] = { 1, 1, 1, 1 }; 
    	style = ST_MULTI;
    	lineSpacing = 1;
    
    };
    ////////////////////////////////////////////////////////
    // GUI EDITOR OUTPUT END
    ////////////////////////////////////////////////////////
    
    };
    };
    

    That was how to define a display resource, such as a HUD. Below is a dialog with essentially the same elements in it:

    class TalkDialog { 
     idd = 1987; 
     movingEnable = false;  // the dialog can be moved with the mouse (see "moving" below) 
     //enableSimulation = false;  // freeze the game 
     controlsBackground[] = { };  // no background controls needed 
     objects[] = { };  // no objects needed 
     controls[] = { RscPicture_1200, 
    	 RscText_1000,
    	 RscText_1001,
    	 RscFrame_1800, 
    	 RscFrame_1801,
    	 RscButton_1600,
    	 RscButton_1601,
    	 RscButton_1602,
    	 RscButton_1603 }; 
    
    
    ////////////////////////////////////////////////////////
    // GUI EDITOR OUTPUT START (by dwringer, v1.063, #Rygyke)
    ////////////////////////////////////////////////////////
    
    class RscFrame_1800: RscFrame
    {
    	idc = 1800;
    	x = 0;
    	y = 0;
    	w = 0.25;
    	h = 0.25;
    };
    class RscPicture_1200: RscPicture
    {
    	idc = 1200;
    	text = "#(argb,256,256,1)r2t(camrender0,1.0)";
    	x = 0.005;
    	y = 0.005;
    	w = 0.24;
    	h = 0.24;
    };
    class RscText_1000: RscText
    {
    	idc = 1000;
    	text = ""; //--- ToDo: Localize;
    	x = 0.25;
    	y = 0;
    	w = 0.75;
    	h = 0.04;
    	colorBackground[] = { 0.1, 0.1, 0.1, 0.8 }; 
            colorText[] = { 1, 1, 1, 1 }; 
    };
    class RscFrame_1801: RscFrame
    {
    	idc = 1801;
    	x = 0.25;
    	y = 0.04;
    	w = 0.75;
    	h = 0.26;
    };
    class RscText_1001: RscText
    {
    	idc = 1001;
    	text = ""; //--- ToDo: Localize;
    	x = 0.25;
    	y = 0.04;
    	w = 0.75;
    	h = 0.26;
    	colorBackground[] = { 0.1, 0.1, 0.1, 0.6 }; 
            colorText[] = { 1, 1, 1, 1 }; 
    	style = ST_MULTI;
    	lineSpacing = 1;
    
    };
    class RscButton_1600: RscButton
    {
    	idc = 1600;
    	text = "1"; //--- ToDo: Localize;
    	x = 0.0125;
    	y = 0.26;
    	w = 0.05;
    	h = 0.04;
    	action = "[DialogTarget, 1] call fnc_diagAct";
    };
    class RscButton_1601: RscButton
    {
    	idc = 1601;
    	text = "2"; //--- ToDo: Localize;
    	x = 0.075;
    	y = 0.26;
    	w = 0.05;
    	h = 0.04;
    	action = "[DialogTarget, 2] call fnc_diagAct";
    };
    class RscButton_1602: RscButton
    {
    	idc = 1602;
    	text = "3"; //--- ToDo: Localize;
    	x = 0.1375;
    	y = 0.26;
    	w = 0.05;
    	h = 0.04;
    	action = "[DialogTarget, 3] call fnc_diagAct";
    };
    class RscButton_1603: RscButton
    {
    	idc = 1603;
    	text = "X"; //--- ToDo: Localize;
    	x = 0.2125;
    	y = 0.26;
    	w = 0.025;
    	h = 0.04;
    	action = closeDialog 0;
    };
    ////////////////////////////////////////////////////////
    // GUI EDITOR OUTPUT END
    ////////////////////////////////////////////////////////
    
    
    };
    

    There's actually a much more detailed post on these forums about how to use #ifdef and some other things to use the same source files to define something as both a dialog and a display, but it's beyond the scope of this thread and I don't remember where it is. :)

    Anyway, where you pull up a dialog with:

    _handle = createDialog "dialogName";

    and end it with closeDialog 0;

    you would pull up the display resource with:

    _handle = 0 cutRsc ["dialogName","PLAIN"];

    and end it with 0 cutRsc ["Default","PLAIN"];

    (assuming you created a default display as seen above)


  10. For sure I have voted this up, and hopefully this gets some more attention ;)

    TBH this would open up so many possibilities - imagine a multiplayer game mode based on the movie Predator :D

    But.. considering how many Sam Fisher type missions Arma games have always had, it would be nice to have at least SOME of the same equipment he has, and not just feel like I am just waiting to get lucky with the timing and my choice of Save Games ;)


  11. Well, the condition to change it from green to red was, I thought, for any OPFOR at all to be present, regardless of BLUFOR, so that condition would need slightly adjusted ;)

    Anyway, the thing you said about making one trigger reset another is exactly why I was suggesting to check if the marker had already changed color in the trigger conditions. Basically triggers are either one-off, or infinitely repeatable (according to their standard behavior, anyway). Thus we would use infinitely repeatable triggers, but be more selective about what it takes to trigger them :)

    Sorry it's really late and I don't have much time to look over this but if I get a chance tomorrow I will return.


  12. In general terms, the solution would be to add a second trigger.

    Looking at the one there, it is set to fire when there are no "resistance" troops (independent, not opfor), and at least one "west" troop (now also known as blufor for consistency, so i recommend changing that too).

    What you need is a trigger to fire when there are 1 or more "opfor" troops that changes the thing red. Then, another trigger, which fires when there are 0 opfor troops, to change the marker green.

    The trigger to turn the marker red must only do so when the marker is not already red, so I would add global variables or find a way to otherwise check the marker color for each trigger. And, of course, the green trigger should only fire when the marker IS red.

    In the syntax you provided,

    {(side _x) == resistance} count thisList == 0 AND {(side _x) == west } count thisList >= 1

    represents the "conditions" of the trigger - what circumstances under which it will fire, so you want to formulate these sections based on the above constraints.

    format["""%1"" setMarkerColor ""ColorGreen"";",_x]

    defines a string of code that executes when the trigger is executed, with the _x going into the place marked %1 and being part of the "foreach" statement enclosing the whole block. (_x represents the current iteration's corresponding array element)

    I realize this is a lot to take on, but you will learn so much by working this out yourself that I hesitate to try and solve it myself. :cool:


  13. floor means the left side of the array will be chosen more often, ceiling meaning the opposite, if you leave both out it will choose completely randomly without weighting.

    Round isn't needed since the count of array elements won't have any decimal numbers (there can't be 0.625 elements in an array).

    I'm afraid this is untrue, and the original objection is valid.

     _selection = _array select floor random count _array;

    would be the correct syntax; "random" always returns a floating point value between 0 (inclusive) and the value passed to it (non-inclusive).

    Thus, if an array has 4 elements,

    _array select random count _array

    would end up as

    _array select random 4;

    which then translates to something like:

    _array select 0;
    //or
    _array select 0.4;
    //or 
    _array select 3.3;
    

    floor and ceiling commands serve to round down, or up, respectively, to the nearest integer. Thus, in the case of using "count <array>" you should use "floor", so you now get an integer 0,1,2, or 3 (assuming the above example of the array having four elements).

    Hopefully this helps somebody at least! :yay:


  14. Nothing easier than that:

    _hel animate ["AddGunHolder",0];
    _hel setvehicleammo 0;

    http://i.imgur.com/ZNd1VUu.jpg (222 kB)

    The first one will make the gun holders disappear, the second one will remove the rockets that are still hovering in the air.

    Cheers

    Hmm, very cool; I had a suspicion there was something like that. However I'm afraid it isn't quite the solution I was looking for. I actually want the rockets still there, and I want the hardpoints visible. Because I am still adding weapons to the helicopter, and when I fire they animate coming from those positions. I just don't want the minigun showing up in the list of weapons when i cycle through them, and afaik that still is not possible without removing the gun holders, as you said. But I appreciate the info; A3 has been out for months and I still keep finding commands from A2 I never really knew about, I am screwed when it comes to keeping up with this series :)


  15. Heh no need to credit my suggestion, I didn't plagiarize anybody but I basically copied others when figuring out how to access the configs :) Anyway, to keep this post on topic, I want to point out that my technique will actually not fill the player's inventory with magazines (if the capacity WOULD fill the player's inventory). For example, if the player has room for 9 magazines plus one in the gun, the player will only get 9 magazines. Instead, add just ONE magazine, then add the weapon, then add the remaining magazines - that way you get all 10. This is a minor issue and not really worth coding a solution IMHO. But it is an issue nonetheless ;)


  16. Gah, sorry man! Try this

    _units = [];
    _backpackarr = ["B_FieldPack_cbr","B_OutdoorPack_tan"];
    _weaponarr = ["LMG_Zafir_F","arifle_Mk20_F"];
    _uniformarr = ["U_IG_Guerilla3_1","U_IG_Guerilla3_2","U_IG_Guerilla1_1","U_IG_Guerilla2_1","U_IG_Guerilla2_2","U_IG_Guerilla2_3","U_IG_leader"];
    _headarr = ["H_Shemag_olive","H_ShemagOpen_khk","H_ShemagOpen_tan"];
    
    {
    if (typeOf _x == "C_man_1") then {
    	_units set [count _units, _x];
    };
    
    } foreach allunits;
    
    if (isServer) then {
    
    {
    
    _backpack = _backpackarr call BIS_fnc_selectRandom;
    _uniform = _uniformarr call BIS_fnc_selectRandom;
    _head = _headarr call BIS_fnc_selectRandom;
    _weapon = _weaponarr call BIS_fnc_selectRandom;
      	_muzzles = getArray(configfile >> "cfgWeapons" >> (_weapon) >> "muzzles"); 
           _unit = _x; // _x will be superceded, below, so rename it so we can still access it
    
    clearItemCargo _x;
    clearWeaponCargo _x;
    clearMagazineCargo _x;
    removeallWeapons _x;
    removeAllHandgunItems _x;
    removeHeadgear _x;
    removeGoggles _x;
    removeUniform _x;
    removeBackpack _x;
    _x addBackpack _backpack;
    _x addHeadgear _head;
    _x addUniform _uniform;
    
      	 { 
          		 if (_x=="this") then { // no longer does _x refer to the unit
    		_mags = getArray(configfile >> "cfgWeapons" >> (_weapon) >> "magazines"); 
    		{ 
    			_unit addMagazines [_x, 10]; 
    		} forEach [_mags select 0]; 
    	} 
    	else { 
    		_mags = getArray(configfile >> "cfgWeapons" >> (_weapon) >> _x >> "magazines"); 
    		{
    				_unit addMagazines [_x, 10]; 
               	} forEach [_mags select 0]; 
            	}; 
       	 } forEach _muzzles;  
    
    _x addWeapon _weapon;
    
    
    } foreach _units;
    
    
    
    };

    Haven't actually tried this but hopefully you can glean the solution if it doesn't work precisely that way. The problem is, my script only gave it to the player, and I think addMagazines only works on units (not unitArrays)


  17. Hmm, the way I have approached that one is as follows:

    private ["_muzzles", "_mags"];
    //<...>
    
    
    _muzzles = getArray(configfile >> "cfgWeapons" >> (_w select 0) >> "muzzles");
    
    {
    	if (_x=="this") then {
    		_mags = getArray(configfile >> "cfgWeapons" >> (_w select 0) >> "magazines");
    		{
    			player addMagazines [_x, 1];
    		}forEach [_mags select 0];
    	} else {
    		_mags = getArray(configfile >> "cfgWeapons" >> (_w select 0) >> _x >> "magazines");
    		{
    			player addMagazines [_x, 1];
    		}forEach [_mags select 0];
    	};
    }forEach _muzzles;

    In the above, "(_w select 0)" is actually just the classname of the weapon, as a string.

    "[_mags select 0]" actually only resolves to one magazine, so you only get one added. Just change the quantity used in the "addMagazines" call if you want to add more than 1.

    The reason for the "foreach" statements is that if you change "[_mags select 0]" to "_mags" it will add one of each type of usable magazine (rather than just the first one found)... although the unit needs carrying capacity or they will not all be added.

    Hope that's not too confusing, but I'll be glad to clarify anything if you have specific questions. Sorry about the "_w select 0" thing, as I said, just replace that with the weapon classname obtained from your random selection. So if you do _weap = <whatever code gets a random weapon classname>; then replace every instance of (_w select 0) with (_weap). That SHOULD cover it but it only takes the first magazine type found, so if the person who coded the muzzle listed supported magazines out of order, you might get tracers instead of normal rounds (or some such).


  18. PSEUDO-RETITLE OF POST:

    "Remove Minigun from AH-9"

    Hey all,

    I created a script back when I was playing TKOH: Rearmed that would allow me to loadout the light attack helicopter with various different loadouts. I decided to see if it would work just as well in Arma 3 (with adjusted classnames), but have run into a snag.

    I cannot figure out how to remove the "default" weapons from the Pawnee. I have not done experiments with other vehicles, but the "removeWeapon '...'" command does not seem to work as it did in TKOH. I have also tried removeAllWeapons to no avail - it does not work to remove weapons I have manually added, either. However, removeWeapon does seem to work on weapons that I have added with addWeapon.

    Here is the code block I am focusing on:

    		
    _hel setVehicleAmmo 0;
    _hel addMagazine "24Rnd_missiles";
    _hel addMagazine "1000Rnd_65x39_Belt_Yellow";
    _hel addMagazine "200Rnd_127x99_mag_Tracer_Red"; 
    _hel addWeapon "LMG_coax";
    _hel removeWeapon "M134_minigun";
    _hel addWeapon "HMG_01"; 
    _hel selectWeapon "LMG_coax";
    

    It adds the weapons/ammo with no problem, and selects the LMG at mission start, but the minigun is still there (with no ammo) when I cycle through vehicle weapons.

    Also, if I don't put the selectWeapon command as the very LAST command, it reselects the minigun by default. Even if i do selectWeapon lmg followed by addweapon HMG, the ammo-less minigun will still be selected on startup.

    So, any clues as to why these features are changed in Arma 3, and any ideas for a workaround? Not game breaking but it is annoying to have an empty weapon there when it's not needed or wanted.

    Thanks!

    ADDED:

    I have done more digging around on the BIS wiki, and apparently while the class info for the AH-9 indeed lists M134_minigun as one of the weapons on this vehicle, the CfgWeapons pages make absolutely no mention of the weapon. It would seem that the M134_minigun is almost "baked in" to the helicopter. Further testing has revealed that I am able to remove the rocket pods, just not the minigun. So, c'est la vie. Probably nothing we can do - but if anyone can show me to be incorrect, I would be very grateful :)


  19. I'm afraid I haven't looked over this much at all, but hopefully there is a command that might be of at least some help.

    If you use "setVectorUp" you can basically align an object's vertical orientation so it is upright (or not). The way to get a piece to be perfectly upright is:

    object setVectorUp [0,0,1];

    This makes the model's "UP" vector correspond to the positive z-axis of the world's coordinates. Essential with static weapons and putting things on roofs, etc.


  20. I am only basing this on the reply that says "you shouldn't use loops that run without any delay in them", with the techniques that I myself use for this issue:

    if (!isServer) exitWith {};
    private ["_veh","_targets","_shoot","_count"];
    _veh = _this select 0;
    _veh setVehicleAmmo 1;
    _targets = [t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13];
    _shoot = true;
    _count = 0;
    _target = _targets select floor(random(count _targets));
    sleep (0.2 + random 0.2);  // Multiple scripts now much less likely to compete in the same frame
    
    while {(_shoot) and (alive _veh)} do {
    _count = _count + 1;
    if (_count == 15000) then { _shoot = false; doStop _veh;};
    _veh doWatch _target;
    _veh action ["useWeapon", _veh, gunner _veh, 0];
           sleep 0.05; // assuming the user gets at least 20fps, this almost as fast as visually perceptible. much longer sleep is usually ok.
    };

    EDIT: sorry, i see now after actually reading the code that the firing occurs every cycle of the loop (if possible). Thus the sleep duration I put as 0.05 will give you a firing rate of 20 rounds a second, or 1200 rounds per minute - probably still much higher than the actual rate of fire. Just find what your weapon's intended firing rate is, and use the appropriate sleep value (60/rds per min).

    There are also commands to order a unit to fire at a target, or to use suppressive fire at a target, but I'm not familiar enough with how they work to see how they may or may not be more suitable here.


  21. Ill just go like "awesomeassscripttodothatonethingthatIneedtodo1.sqf" then "awesomeassscripttodothatonethingthatIneedtodo2.sqf"..etc :P

    Nonsense. Much better simply to extend filenames to 3-4x their original length. Ever since Win95 introduced "long filenames" a filename is like an intro paragraph to a file. That's why MS Word uses the first lines of your papers to title them by default!


  22. The _null thing isn't really necessary anyway. It makes sense inside the editor, because the engine won't allow unbound return values from init calls or whatever else. i.e., we do it as a convention to suppress the error and name the variable _null or _nil because it is immediately discarded by the game anyway.

    If you're inside of a script, you are actually binding the variable _null which is treated like any other machine-local variable. This breaks another convention because we generally use underscore (_) to denote a variable local to a particular script, and declared with "private" in the scope where it is used.

    If you don't need the value, don't assign a variable if you don't have to :)

×