Jump to content

alpha993

Member
  • Content Count

    94
  • Joined

  • Last visited

  • Medals

  • Medals

Everything posted by alpha993

  1. alpha993

    Uniform

    Yep. You can also see the correct classname when you hover over the uniform in the arsenal, so you can just write that instead of going through the whole export process. Btw, just for future reference, the 'TAG' before the variable names is a personalized three-letter tag to prevent overwriting by similarly-named variables. You should use something like ROK_uniform, for example.
  2. alpha993

    Uniform

    Ahh, I see the issue. The classname you wrote is the folded-up uniform object and not the actual uniform. Try this instead: [ TAG_uniform, "Put on disguise", "\a3\ui_f\data\igui\cfg\actions\take_ca.paa", "\a3\ui_f\data\igui\cfg\actions\take_ca.paa", "_this distance _target < 3", "_caller distance _target < 3", {}, {}, { player forceAddUniform "U_O_CombatUniform_oucamo"; deleteVehicle TAG_uniform;}, {}, [], 5, 999, true, false ] call BIS_fnc_holdActionAdd;
  3. alpha993

    Uniform

    I just tested it on my end and it worked correctly. May I take a look at the code you used with the classname?
  4. There's a handy function called BIS_fnc_fireSupportVirtual you can use to call the artillery bombardment. You can easily randomize any of the parameters inside. If you want to really randomize the location where the artillery can land, you can use BIS_fnc_randomPos or BIS_fnc_findSafePos to get a target location. Alternatively, you can place several empty system markers on pre-defined locations where the artillery could fire. I'll give you an example script using each method below: Example with BIS_fnc_randomPos Get the coordinates of the center of your village, or place an empty system marker (I will use an empty marker). Name the system marker something like TAG_artilleryCenter; Place two triggers (if you want them to be invisible), or two area markers covering the two locations you want to be safe from artillery (I will use triggers). Name each trigger or area marker something like TAG_safeZone_1 and TAG_safeZone_2. Run the following code whenever you want an artillery strike: _TAG_artilleryRadius = 100; // Set village radius in meters _TAG_artillerySpread = 5; // Set artillery spread radius (the accuracy of the rounds, in essence) _TAG_artilleryRounds = 10; // Set how many rounds will be fired _TAG_artilleryDelay = [1,2]; // Set the minimum and maximum delay between rounds in seconds _TAG_selectedPos = [[[getMarkerPos "TAG_artilleryCenter", _TAG_artilleryRadius]], ["water", TAG_safeZone_1, TAG_safeZone_2]] call BIS_fnc_randomPos; // Get random position in a circle centered on TAG_artilleryCenter marker, within a predefined radius (100 meters in this example), excluding the two safe zones and water [_TAG_selectedPos, "Sh_82mm_AMOS", _TAG_artillerySpread, _TAG_artilleryRounds, _TAG_artilleryDelay] spawn BIS_fnc_fireSupportVirtual; // Fire artillery with defined parameters Example with BIS_fnc_findSafePos Get the coordinates of the center of your village, or place an empty system marker (I will use an empty marker). Name the system marker something like TAG_artilleryCenter; Place two triggers (if you want them to be invisible), or two area markers covering the two locations you want to be safe from artillery (I will use triggers). Name each trigger or area marker something like TAG_safeZone_1 and TAG_safeZone_2. Run the following code whenever you want an artillery strike: _TAG_artilleryRadius = 100; // Set village radius in meters _TAG_artillerySpread = 5; // Set artillery spread radius (the accuracy of the rounds, in essence) _TAG_artilleryRounds = 10; // Set how many rounds will be fired _TAG_artilleryDelay = [1,2]; // Set the minimum and maximum delay between rounds in seconds _TAG_selectedPos = [getMarkerPos "TAG_artilleryCenter", 0, _TAG_artilleryRadius, 0, 0, 0, 0, [TAG_safeZone_1, TAG_safeZone_2]] call BIS_fnc_findSafePos; // Get random position in a circle centered on TAG_artilleryCenter marker, within a predefined radius (100 meters in this example), excluding the two safe zones and water _TAG_selectedPos pushBack 0; [_TAG_selectedPos, "Sh_82mm_AMOS", _TAG_artillerySpread, _TAG_artilleryRounds, _TAG_artilleryDelay] spawn BIS_fnc_fireSupportVirtual; // Fire artillery with defined parameters Example with pre-defined empty markers Place several empty system markers on locations you want to be possibly hit by artillery. Name the system markers something like TAG_artilleryTarget_1, TAG_artilleryTarget_2, TAG_artilleryTarget_3, and so on. Run the following code whenever you want an artillery strike: _TAG_artilleryRadius = 100; // Set village radius in meters _TAG_artillerySpread = 5; // Set artillery spread radius (the accuracy of the rounds, in essence) _TAG_artilleryRounds = 10; // Set how many rounds will be fired _TAG_artilleryDelay = [1,2]; // Set the minimum and maximum delay between rounds in seconds _TAG_selectedPos = getMarkerPos selectRandom ["TAG_artilleryTarget_1", "TAG_artilleryTarget_2", "TAG_artilleryTarget_3"]; // Select a random target marker and get its position. Add as many target markers as you have placed in the editor [_TAG_selectedPos, "Sh_82mm_AMOS", _TAG_artillerySpread, _TAG_artilleryRounds, _TAG_artilleryDelay] spawn BIS_fnc_fireSupportVirtual; // Fire artillery with defined parameters ______________________________________ You can naturally randomize the artillery radii, spreads, rounds, and delays using the random command as well, or you can make them parameters and change them whenever you call the scripts. Each code snippet should also be placed in a script file in your mission directory, called something like artilleryStrike.sqf and executed like so: nul = [] execVM "artilleryStrike.sqf"; Hope this helps!
  5. alpha993

    Uniform

    Did you replace "uniformClass" in the action with the classname of the uniform you want to put on?
  6. nul = [ position player, "EXAMPLE TEXT", 270, 310, 10, 1, [["\A3\ui_f\data\map\markers\nato\b_inf.paa", [0,0.3,0.6,0.7], position player, 1, 1, 0, "NATO", 0]] ] spawn BIS_fnc_establishingShot; Try it like this. You had an extra comma at the end of the icon array. To illustrate: [foo, bar, bas] is a correct array, but [foo, bar, bas, ] will throw an error.
  7. alpha993

    Uniform

    Perhaps you could attach an action to the uniform object on the desk (assuming you've actually placed the uniform on top and not in an inventory). That way you can use the action to run forceAddUniform as johnnyboy suggested. Name the uniform object TAG_uniform and execute the following in the init or another script: [ TAG_uniform, "Put on disguise", "\a3\ui_f\data\igui\cfg\actions\take_ca.paa", "\a3\ui_f\data\igui\cfg\actions\take_ca.paa", "_this distance _target < 3", "_caller distance _target < 3", {}, {}, { player forceAddUniform "uniformClass"; deleteVehicle TAG_uniform;}, //Replace "uniformClass" with the classname of the uniform you want {}, [], 5, 0, true, false ] call BIS_fnc_holdActionAdd;
  8. In order to loop the sound you'll have to execute the Say3D command again once the sound becomes null. I would recommend doing this in another script and not in the radio's init for readability. Make a script called playMusicRadio.sqf and place the following inside: TAG_radioOn = true; _TAG_song = _this #0; if (isServer) then { // adds the action to every client and JIP [ TAG_myRadio, // Object the action is attached to "Turn off radio", // Title of the action "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_connect_ca.paa", // Idle icon shown on screen "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_connect_ca.paa", // Progress icon shown on screen "_this distance _target < 3", // Condition for the action to be shown "_caller distance _target < 3", // Condition for the action to progress {}, // Code executed when action starts {}, // Code executed on every progress tick { TAG_radioOn = false; // Code executed on completion publicVariable "TAG_radioOn"; removeAllActions TAG_myRadio; }, {}, // Code executed on interrupted [], // Arguments passed to the scripts as _this select 3 3, // Action duration in seconds 999, // Priority true, // Remove on completion false // Show in unconscious state ] remoteExec ["BIS_fnc_holdActionAdd", 0, TAG_myRadio]; // MP compatible implementation }; while {TAG_radioOn} do { _TAG_soundSource = TAG_myRadio say3D [_TAG_song, 40, 1, true, 0]; waitUntil {(isNull _TAG_soundSource) || !(TAG_radioOn)}; }; deleteVehicle _TAG_soundSource; Then, place the following in the radio's init: nul = ["resonance"] execVM "playMusicRadio.sqf"; That should do the trick. _____________________________________ This is probably because your song file is stereo. For positional audio to work as intended, you should make sure it's a mono .ogg file.
  9. Hey all, I've been trying to pass a variable containing an array into the mission parameters in my description.ext using preprocessor commands, but I've had no luck so far. I'm not very familiar with the preprocessor commands as it is, so I'd greatly appreciate if anyone could point me in the right direction. What I'm trying to do step-by-step: Create two 'string' arrays in a preInit function, one with just numbers, and the other with just strings. e.g. ALP_arrayNum = "0, 1, 2, 3, 4, 5" & ALP_arrayText = " 'zone0', 'zone1', 'zone2', 'zone3', 'zone4', 'zone5' " Store those 'string' arrays into two variables. see example above. Compile the variables so that they get the braces required by config arrays. ALP_arrayNum becomes {0, 1, 2, 3, 4, 5} ALP_arrayText becomes {'zone0', 'zone1', 'zone2', 'zone3', 'zone4', 'zone5'} Declare those variables in the description.ext using preProcessor commands. Using __EXEC or __EVAL? Define the values[] and texts[] attributes in the params class using those two variables. This way I can achieve a dynamic parameter that doesn't need to be rewritten by hand whenever the mission is modified or ported to other maps. // === PARAMETERS class Params { class ALP_selectedArea { title = "Main Zone"; values[] = {}; //<--------DEFINE THIS WITH VARIABLE CONTAINING ARRAY OF NUMBERS texts[] = {}; //<--------DEFINE THIS WITH VARIABLE CONTAINING ARRAY OF STRINGS default = 0; }; }; My attempts: #1 -- This one throws a "_ found, { expected" error // === PARAMETERS class Params { class ALP_selectedArea { title = "Main Zone"; values[] = __EVAL(ALP_arrayNum); texts[] = __EVAL(ALP_arrayText); default = 0; }; }; #2 -- This one doesn't throw an error, but returns 'any' in the params menu, presumably because it's actually duplicating the braces like values[] = {{0, 1, 2, 3, 4, 5}} // === PARAMETERS class Params { class ALP_selectedArea { title = "Main Zone"; values[] = {__EVAL(ALP_arrayNum)}; texts[] = {__EVAL(ALP_arrayText)}; default = 0; }; }; #3 -- This one behaves like #1, where it throws a "_ found, { expected" error // === PARAMETERS #define ZONEVAL values[] = __EVAL(ALP_arrayNum); #define ZONETXT texts[] = __EVAL(ALP_arrayText); class Params { class ALP_selectedArea { title = "Main Zone"; ZONEVAL ZONETXT default = 0; }; }; Again, any help would be greatly appreciated!
  10. I have a mission that creates an area of operations by selecting one trigger out of several placed in the editor. I then have a parameter which tells the game to either pick a trigger randomly, or select a specific one (only one area of operations is active during the mission, similar to King of the Hill). The reason I wanted a dynamic parameter is so I can add or remove triggers, and have the parameter automatically update itself accordingly. Otherwise, I would have to manually type in each trigger, which gets tedious when you have over twenty. Such an automated approach would also make it extremely simple to port the mission to other maps, as all you would need to do is place your triggers and not worry about editing the parameters. In any case, I made an alternative approach by creating a function that detects all triggers and then writes the parameter config for me. It's not the fully automated system I was hoping for as I have to run the function every time I port the mission or make significant changes, but it's better than typing everything manually.
  11. playSound3D works through the game's sound channel, and since you're deactivating the sound with 0 fadeSound 0, you won't hear anything out of the radio. If you play your sound using say3D instead, you can set the isSpeech parameter to true, where the game will play the sound over the speech channel independently from fadeSound. Make sure your custom sound is defined in description.ext through cfgSounds and then play your sound like this: TAG_myRadio say3D ["resonance", 40, 1, true, 0]; Where TAG_myRadio is your radio object, "resonance" is your sound file defined in description.ext, 40 is the max audible distance (might want to increase this), 1 is the pitch, true is the fadeSpeech parameter, and 0 is the sound offset.
  12. I forgot that __EVAL only returns numbers or strings, so I'm pretty much out of luck with this since I need to return a curly bracketed array. The alternative would be to use a different variable for each element of the array (like in BI's paramCountdown.inc file), but that would just be too much of a headache for this approach to be worth it, especially considering my arrays would vary in size. For example, here's how BI does it in paramCountdown.inc, where each _countdown variable is defined previously in an __EXEC command: values[] = { -1, __EVAL(_countdown0), __EVAL(_countdown1), __EVAL(_countdown2), __EVAL(_countdown3), __EVAL(_countdown4), __EVAL(_countdown5), __EVAL(_countdown6), __EVAL(_countdown7), __EVAL(_countdown8), __EVAL(_countdown9), __EVAL(_countdown10) };
  13. I gave it a shot, but the best I get is a <null> in the parameters. class Params { class ALP_testParam { title = __EVAL(parsingNamespace getVariable ["ALP_test","test"]); values[] = {__EVAL(parsingNamespace getVariable "ALP_arrayNum")}; texts[] = {__EVAL(parsingNamespace getVariable "ALP_arrayText")}; default = 0; }; }; I'm pretty sure PreInit functions just don't run until after the mission lobby, as the "ALP_test" variable in the title was defined as "paramTitle" in the PreInit, but it's instead showing up as the default "test," meaning it's undefined.
  14. I have, but no matter what I do the variables aren't passed successfully. I've tried dozens of approaches and the best I can get is the variables returning "any." I'm starting to think it's not possible to use preInit-defined variables as they seem to not get their values until after the lobby screen.
  15. What I would do is to get the marker data and store it into each player's profileNamespace. This way you don't need to worry about exporting anything as all the data will be stored in the profiles of each player who played the first mission. In your first mission (make sure whatever script it's on is local to the player): TAG_markerData = allMapMarkers; // Replace this with your data collection method profileNamespace setVariable ["TAG_markerData", TAG_markerData]; saveProfileNamespace; In your second mission (ideally in initPlayerLocal.sqf): TAG_markerData = profileNamespace getVariable ["TAG_markerData",false]; // Returns false if undefined profileNamespace setVariable ["TAG_markerData",nil]; // Clear data from profile as it is no longer needed saveProfileNamespace; // spawn your markers as needed
  16. Could you provide some more details on what exactly you want to accomplish? I'd be happy to help!
  17. Hey everyone, I'm making a script that allows you to kick open a door to make breaching slightly faster. However, I do not want players to be able to kick open doors that open towards them, as that would be rather strange to say the least. In order to accomplish this, I need a way to determine if a door will open away from or towards a player, depending on which side they're standing on. I have the following script which works fine for some doors. It gets the coordinates of the door in the player's model space when it's closed and open, and then checks if the difference is negative. However, some doors seem to be mirrored in-game with their selection coordinates not really matching up with the in-game model. So when a door opens away from the player, the coordinates show that it should actually open towards the player. _building = cursorObject; _doorSelection = ((selectionNames _building) select {((_building modelToWorldVisual (_building selectionPosition _x)) distance2D player < 1.5) AND (("door" in toLower _x)) AND !(("handle" in toLower _x))}) select 0; _doorAnimation = format ["%1_rot", _doorSelection]; _doorAnimationPhase = _building animationPhase _doorAnimation; _doorCenterPosStart = player worldToModel (_building modelToWorld (_building selectionPosition _doorSelection)); _building animate [_doorAnimation,1,true]; _doorCenterPosEnd = player worldToModel (_building modelToWorld (_building selectionPosition _doorSelection)); _building animate [_doorAnimation,_doorAnimationPhase,true]; _opensInwards = ((_doorCenterPosStart select 1) - (_doorCenterPosEnd select 1) < 0); Is there some other way to figure this out? Because at the moment the alternative is increasingly looking like I'll have to brute force it and make a list of every door in every building 😕 Any help would be greatly appreciated!
  18. I didn't end up using your code per se, but it did help me arrive at a different solution which suited my needs, so thank you for that! 🙂 I'm going to post here my solution for finding whether a door opens away from or towards the player using it in case anybody else runs into similar issues. First though, let me illustrate the issue I was encountering a little more clearly. In this first picture, you can see what is a normal door with its selections in the correct place. The green one corresponds to the door's axis (_building selectionPosition "door_1_axis"), the red one to the door's center position (_building selectionPosition "door_1_trigger"), and the blue one to the standard position (_building selectionPosition "door_1"). Ideally, you'd be able to tell in which direction a door opens by instantly opening and closing it with the animate command (the player will not see this as it's too fast), and getting the relative coordinates of the standard blue position to the player in both the closed and opened states. The difference between them will tell you if the door opens towards the player or away from the player depending on whether the difference is negative or positive. This is all fine and dandy except for the fact that some doors are mirrored such as the one in the picture below. In this case, the blue position stays on the axis when the door is moved, reversing the result from taking the difference of the relative coordinates. In simpler terms, the code will say the door opens towards the player, when in fact it does not. Initially I thought about comparing 2D distances between the axis and the blue point to determine if a door was mirrored, but this turned out to be inconsistent. As a result, I turned to finding the angle between two 2D vectors, those being the vector from the axis to the red center, and the vector from the axis to the blue point. After some testing, I found that mirrored doors had angles greater than 50 degrees (Note that there might be exceptions still!), so I made the code check for this angle and then reverse the calculation if it detected the larger angles. So far, I have found it to be reliable enough for my purposes. Here is the code I used with annotations. Hopefully it's a useful starting point or even a solution for anyone who requires it. params ["_building","_doorSelection"]; // Define building and desired door // COLLECT DOOR INFO _doorCenter = _building selectionPosition format ["%1_trigger", _doorSelection]; // Get door center coordinates in building's model space _doorAxis = _building selectionPosition format ["%1_axis", _doorSelection]; // Get door axis coordinates in building's model space _doorMain = _building selectionPosition _doorSelection; // Get door standard position coordinates in building's model space _doorAnimation = format ["%1_rot", _doorSelection]; // Get door animation name _vectorAxisToCenter = _doorAxis vectorFromTo _doorCenter; // Get vector from door axis to door center _vectorAxisToCenter set [2, 0]; // Make 2D vector _vectorAxisToMain = _doorAxis vectorFromTo _doorMain; // Get vector from door axis to door standard pos _vectorAxisToMain set [2, 0]; // Make 2D vector _angle = acos (_vectorAxisToCenter vectorCos _vectorAxisToMain); // Get angle between vectors // ANIMATE TO FIND DIRECTION _doorAnimationPhase = _building animationPhase _doorAnimation; // Get current animation phase // Get door standard position's coordinates in player's model space before animating _doorMainPosStart = player worldToModelVisual (_building modelToWorldVisual (_building selectionPosition [_doorSelection, "Geometry"])); _building animate [_doorAnimation,1,true]; // Open the door instantly // Get door standard position's coordinates in player's model space after animating _doorMainPosEnd = player worldToModelVisual (_building modelToWorldVisual (_building selectionPosition [_doorSelection, "Geometry"])); _building animate [_doorAnimation,_doorAnimationPhase,true]; // Return the door to its original animation phase instantly // DEFINE RETURN VARIABLE _opensAwayFromPlayer = if (_angle < 50) then // Check for angle (door is mirrored if it is greater than 50 degrees) { ((_doorMainPosStart select 1) - (_doorMainPosEnd select 1) < 0); // If true, use regular formula } else { ((_doorMainPosEnd select 1) - (_doorMainPosStart select 1) < 0); // If false, use inverted formula }; _opensAwayFromPlayer // Return true if the door opens away from the player
  19. Thanks for the reply! I'll work with it soon and let you know how it goes.
  20. I'm glad I could help! For logging the coordinates you might want to look at the diag_log command. With it you should be able to output the dimensions of the frame.
  21. alpha993

    circle pop up animation

    drawIcon3D would also be my guess. Looks like a simple circular icon with its height and width changing over time, with the alpha value in the color slowly decreasing accordingly. Then it's just executed twice to show the double circle effect. It should also be possible to do it using ui controls, but drawIcon3D would be much easier in my opinion.
  22. My pleasure! Just a note based on the other comments: my script uses triggers because they are visible both in the 2D and 3D views of the editor, which in my experience makes it a little easier to work with the areas. However, if you don't need the 3D view you can just place the markers in the editor and edit the script to use them directly instead of spawning them.
  23. Glad it worked out! But yeah, event handler parameters usually are the values of what triggered them, so simple conditionals like if statements are always useful to restrict when the handlers actually execute their code.
  24. Oh I forgot to mention that the script allows for the areas to be of any size and any shape, so you can have elliptical areas as well!
  25. All right, so I managed to put something together. The following script will automatically register all triggers you put down with a certain variable name stem (in this case, all triggers that start with "ALP_area" are counted), creating the necessary markers in accordance to the triggers' dimensions and orientation. It then checks every five seconds inside the trigger area for enemies and 'blacklisted' items, turning the marker red if it detects any and green if not. You are able to customize the blacklists however you see fit, so you could have an IED turn the marker red, but a NATO Apers mine leaving it green, for instance. All you have to do to put it into your mission is to create a script file in your mission directory called ALP_areaMarkers.sqf — then put the following code inside. Afterwards, create an init.sqf file if you haven't already and place the following inside: if (isServer) then { nul = [] execVM "ALP_areaMarkers.sqf"; }; In terms of mission set-up, all you need to do is place down triggers (You don't need to put down any markers!) and name them ALP_area_1, ALP_area_2, ALP_area_3, and so on. The script takes care of the rest. (You could even call them ALP_area_foo, ALP_area_bar, or anything else. The important part is just the stem) This is how it should look in the editor: And this is the result in-game with some areas hostile and some cleared: Hope this helps! If you have any questions or run into any issues please don't hesitate to let me know!
×