Jump to content

alpha993

Member
  • Content Count

    52
  • Joined

  • Last visited

  • Medals

  • Medals

Community Reputation

71 Excellent

2 Followers

About alpha993

  • Rank
    Lance Corporal

Recent Profile Visitors

728 profile views
  1. 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
  2. Thanks for the reply! I'll work with it soon and let you know how it goes.
  3. 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.
  4. 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!
  5. 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.
  6. 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.
  7. 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.
  8. 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!
  9. 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!
  10. I would suggest looking into the FiredNear eventhandler, as it can detect when shots are fired near a unit and even thrown stuff like grenades since Arma 3 1.30. For example, you can add it to the civilians in question ( or just the group leaders) and then use it to give them a simple move command to somewhere else. To illustrate, try putting this into the init field of a civilian or civilian group leader: this addEventHandler ["FiredNear", { params ["_unit", "_firer", "_distance", "_weapon", "_muzzle", "_mode", "_ammo", "_gunner"]; group _unit setSpeedMode "FULL"; group _unit setCombatMode "BLUE"; group _unit setBehaviourStrong "AWARE"; group _unit move getMarkerPos "civsFleeToHere"; // <---- Replace civsFleeToHere with the marker var name of your choosing }]; You might want to play around with the values of the commands inside like combatMode and behaviour to get exactly what you're looking for.
  11. I could most likely write a script for you that should take care of all that automatically. All you would need to do is set up triggers with the sizes you want and the script would generate the accompanying marker and handle the color. I'll see what I can come up with and post it back here for you.
  12. alpha993

    Need fast reload advice

    Total stab in the dark here (I don't really know that much about how the animations system in the game works), but this might be useful to you. I would personally recommend using this is a rough guide to help look for the actual MX reload gesture in the game files and work from there. class CfgGesturesMale { class ManActions; class Actions; class Default; class States { class myGestureName: Default { file = "a3\anims_f\data\anim\sdr\gst\gesturereloadmx.rtm"; // <---- Existing anim that might look good for dropping a mag. MX one for reference. looped = 0; speed = 0.8; // <---- Variable to speed it up however you like! For reference, MX speed is 0.37. duty = 1; aimingBody = "aimingUpDefault"; mask = "handsWeapon"; soundOverride = ""; leftHandIKBeg = 1; leftHandIKCurve[] = {1}; leftHandIKEnd = 0; rightHandIKBeg = 1; rightHandIKCurve[] = {}; rightHandIKEnd = 1; weaponIK = 0; enableOptics = 0; showWeaponAim = 1; disableWeapons = 1; disableWeaponsLong = 1; canPullTrigger = 0; }; };
  13. alpha993

    Need fast reload advice

    There is the default Arma 2 style reload animation which you could use with: player playAction "ReloadMagazine" I think it's slightly faster than regular animations, so it's a start I guess.
  14. alpha993

    Need fast reload advice

    Normally you'd be able to control an animation's speed with setAnimSpeedCoef, but reload animations are considered gestures/actions, so that command does not affect their speed. You'd probably need to create a new gesture or modify an existing one via an addon. However, you could likely find an existing regular animation that looks good enough and use that instead with the aforementioned command, resetting the animation speed after the reload is done (important since you don't want your character zooming around with super speed).
  15. I modified the script to create a 2D effect instead as you've indicated. It's similar to the previous script but converts the world coordinates of the bounding box to screen coordinates using worldToScreen. It then checks if all coordinates are inside the screen space before rendering the frame. The script could definitely be simplified some more, but it works well as is. (findDisplay 46) ctrlCreate ["RscFrame",999]; // Create frame control ALP_boundingBoxShow = true; // Define variable to end the script with ALP_boundingBoxScreen = addMissionEventHandler ["EachFrame", { _object = cursorObject; // Get object under cursor _boundingBox = 0 boundingBoxReal _object; // Get object bounding box _color = [0,1,1,1]; // Define bounding frame color in format [Red,Green,Blue,Alpha] _ctrlFrame = (findDisplay 46) displayCtrl 999; // Define local variable for frame control _ctrlFrame ctrlSetTextColor _color; // Color the frame // Hide the frame if not looking at anything if (isNull _object) then { _ctrlFrame ctrlShow false; } else { _ctrlFrame ctrlShow true; }; // Split coordinates _x1 = (_boundingBox #0) #0; _y1 = (_boundingBox #0) #1; _z1 = (_boundingBox #0) #2; _x2 = (_boundingBox #1) #0; _y2 = (_boundingBox #1) #1; _z2 = (_boundingBox #1) #2; // Get all box vertex coordinates in world-coordinate space, then translate to screen-coordinate space _vR1 = worldToScreen (_object modelToWorldVisual [_x1,_y1,_z1]); _vR2 = worldToScreen (_object modelToWorldVisual [_x2,_y1,_z1]); _vR3 = worldToScreen (_object modelToWorldVisual [_x2,_y1,_z2]); _vR4 = worldToScreen (_object modelToWorldVisual [_x1,_y1,_z2]); _vR5 = worldToScreen (_object modelToWorldVisual [_x2,_y2,_z2]); _vR6 = worldToScreen (_object modelToWorldVisual [_x1,_y2,_z2]); _vR7 = worldToScreen (_object modelToWorldVisual [_x1,_y2,_z1]); _vR8 = worldToScreen (_object modelToWorldVisual [_x2,_y2,_z1]); // Check if all vertices are visible, then display frame if ({ count _x == 2 } count [_vR1, _vR2, _vR3, _vR4, _vR5, _vR6, _vR7, _vR8] == 8) then { _xC = [_vR1 #0, _vR2 #0, _vR3 #0, _vR4 #0, _vR5 #0, _vR6 #0, _vR7 #0, _vR8 #0]; // Get all X coordinates _yC = [_vR1 #1, _vR2 #1, _vR3 #1, _vR4 #1, _vR5 #1, _vR6 #1, _vR7 #1, _vR8 #1]; // Get all Y coordinates // Get maxima and minima for frame dimensions _xMin = selectMin _xC; _yMin = selectMin _yC; _xMax = selectMax _xC; _yMax = selectMax _yC; _ctrlFrame ctrlSetPosition [_xMin,_yMin,abs(_xMax - _xMin),abs(_yMax - _yMin)]; // Set frame dimensions }; _ctrlFrame ctrlCommit 0; // Display frame with specified parameters }]; // Remove event handler and frame control when variable is false waitUntil {!ALP_boundingBoxShow}; removeMissionEventHandler ["EachFrame",ALP_boundingBoxScreen]; ctrlDelete ((findDisplay 46) displayCtrl 999); To stop the script just run the following command: ALP_boundingBoxShow = false; And here is what the result looks like in-game. It works with all objects detectable with the cursorObject command. Note that some vehicles have strangely tall bounding boxes. This could be remedied by attaching a multiplier to the Y-coordinate depending on whether the cursor object is a car or tank (e.g. _object isKindOf "tank"). Hope this helps!
×