Jump to content

ZaellixA

Member
  • Content Count

    361
  • Joined

  • Last visited

  • Medals

Everything posted by ZaellixA

  1. Yeah, I get your approach and the reasoning behind it, thanks. To be honest, I haven't looked at the script you created so I can't really suggest anything, but maybe you could modify/extend it to scan for all 3den placed vehicles at the start of the mission and get the mass of those vehicles. There may be a chance that the players or mission creators won't use more than those vehicles. So, the need to run the script after the mission start will be reduced to the spawn of new types of vehicles. You could make the script to use some kind of memoization in order to avoid being executed for the same type of vehicle more than once. I am just throwing suggestions here from an end-user's perspective and not implying that the script needs improvements. As I said, I haven't seen the script so I can't really have an opinion on the implementation.
  2. OK, so this is more of a "safeguard" than an actual necessity to get the mass of the vehicle right? I mean, that you could very well place a vehicle in the 3den editor and then use the same command on it to get the mass, then delete it... Do I understand it correctly or am I missing something??
  3. @Waldemar 337 thanks for the answer, but to be honest I should be more precise. Is there a good reason to make a vehicle up in the sky rather than creating it on terrain and then deleting it right after you acquire the information you need?
  4. If you don't mind me asking, why do you add a random value to the z coordinate of the vehicle's position? Does it provide any kind of benefit to your task? I don't really know exactly how getMass works and so I cannot understand why a vehicle has to be flying high in order to get its mass but I trust that you have tested the function and works "properly".
  5. Good to see all those privates up there 🙂. Regarding the tag though, keep in mind that this is just a suggestion to provide consistency and coding style that matches the community's (which most often than not is built upon well thought and "engineered" guidelines). If you have taken your actions under consideration or this is what you've designed. don't hesitate to follow whatever is that you designed.
  6. ZaellixA

    Critique My Scripting

    You got some nice comments from the people here. I just have to add a wee bit of a minor detail. In your inner while-loop you check for a condition you have already checked on the outer while-loop, essentially checking it twice for no obvious (to me) reason. You could actually either combine those two while-loops into just the inner one or get rid of the _totalSpawned < _maxAIToSpawn from the second loop. It won't make any difference on the performance side but I believe it's good practice to keep your code as clean as possible and communicate your intends as precisely as possible. It will help in debugging and maintenance. Otherwise a very nice script to start with 🙂.
  7. Congrats on the release. Just a couple of small things to kinda improve your code. I strongly suggest you use the keyword private to declare your private variables. This way you'll make sure there's absolutely no naming conflict (if you haven't f**ked up your own code that is). Additionally, you may want to add some kind of tag to your variables. This could be your initials, some other meaningful (to you and possibly others) initials, some initials resembling the script or mod etc. A couple of examples (borrowing your variable names) are private _VBIED_SuicidalMethod = 1; private _VBIED_Death_Shout = "SuicideCry"; Of course, having a tag in private variables may not make much sense but I usually do it in my code to clarify things and have a consistent format in case I also use global and/or public variables. Keep up the good work and thanks for sharing with the community.
  8. Trying to follow on the steps of Harzach and _foley I suggest something like (feel free to adapt to your liking and needs) { private _unit = _x; // Get the (each) unit first { private _car = _x; // Now get the car private _dist = _unit distance _car; // Calculate the distance if ((isPlayer _unit) && (_dist < _dangerClose)) then { // You have to make sure _dangerClose must be "visible"/known in this scope private _playerNearest = _unit; // Set nearest player private _dangerClose = _dist; // Set the closest distance }; } forEach _carsArray; } forEach playableUnits; Don't really know how efficient this can be nor I have tried to find a better optimised version of it. I just did a "direct translation" of your pseudocode to this. Hope this helps somehow. Just keep in mind that this snippet is not tested and should be treated with care.
  9. Hey all, back here with a question. I am looking for a way to get access to some variables which have the same name with an increasing numerical suffix. I tried to do something like this but to no avail // Trying to get access to objects named (in the editor) obj0, obj1, obj2, obj3, etc. private _maxIdx = 4; // I get this from somewhere else but I define it here for completeness // Increase an index for[{private _i = _0}, {_i < _maxIdx}, {_i = _i + 1}] do { // Create the name of the variable private _var = "obj" + (str _i); // Parse the name of the variable as a string _var = call (compile _var); // Get the object variable // Get the position of the object _secPos set[_i, getPosATL _var]; // Get the position of the object placed in the sector // Delete the object placed at the sector objective deleteVehicle _var; }; This doesn't seem to work. The only evidence I have (haven't done the testing myself unfortunately) is that the objects (obj0, obj1, obj2, etc.) are not deleted in the editor. Any ideas or insights are most welcome :).
  10. Hey there SophionBlack. You already got quite some info on your issue. I'll just add what I did to solve my issue. Well actually, as i said above, there was no problem apart from the fact that the variables were not named prorperly in the editor. Nevertheless my approach was the following. Create a string containing the name of the object/entity as it is named in the editor. Use compile to turn that string into actuall code, effectively turning it into a statement. Of course you have to call that code to be effectively used... Use the returned value of compile as the right-hand side of an assignment statement to save the entity/object (which is the string turned into code) into a variable. Use the variable at will, according to my needs. This is how I actually got access in script to the objects I wanted to use, without having to hardcode each and every one of their names. Of course this means that they have to be named accordingly in the editor, which as I have already mentioned was not the case initially. As you can see, this approach can introduce problems if you are not careful enough. Nevertheless, it served me quite well in occassions, such as when you want to get access to many practice targets where they may be named, for example, pTarg0, pTarg1, pTarg2, ... A code snippet is shown below demonstrating the said steps (numbered for ease of reference) // Assume the variables are named obj0, obj1, obj2 in editor // Create some parameters private _nObj = 3; // Define number of objects to get private _objs = []; // Iniitalise array to hold the objects // Create the strings holding the names of the objects (1) for ({private _i = 0}; {_i < nObj}; {_i = _i + 1}) do { private _temp = "obj" + (str _i); // Here the the string "obj0", "obj1" and "obj2" are created (1) _objs pushBack call (compile _temp); // Here I compile the string held in _temp to create the code [obj0], [obj1] and [obj2] and then add it to the array (2) + (3) }; // At this point the array objs contains [obj0, obj1, obj2] which are the objects of interest // Now you could possibly make the array global or whatever. I go with setVariable here for demonstration missionNamespace setVariable ["myArrayOfObjects", objs, true]; // I also make it public with the last argument The only difference here from the steps mentioned above is that I actually push back the objects into an array instead of using them in an assignment. I am not sure how close is that to what you want to achieve. If not, apologies for the clutter but if it helps anyhow and you would require clarifications and or more info please don't hesitate to ask.
  11. ZaellixA

    Launcher does not start on mac os

    That's a positive. I do have a Mac and had Windows installed via Bootcamp in order to be able to test scripts that I was making back then... It wasn't a good option because even before BI quit the support and development of the Mac version of ArmA, its version was lagging quite heavily compared to that on PC. Anyway, you could possibly still play ArmA 3 on Mac but keep in mind that it will be a quite old version and most probably you won't be able to play with other players (you must have the same version and I don't know many who don't run the latest one).
  12. Harzach is very much spot on. I just wanna show some alternatives and a more generic way of getting a random number (just so that you can pick different ranges too). So, if you would like to get a random number in a specific range [a, b] (both a and b inclusive) you could do something like // I assume this is a function so I get the passed parameters params[["_min", 0, [0]], // Minimum of the range ["_max", 100, [0]]]; // Maximum of the range // Calculate random number private _rand = min + random[max + 1]; // Return the number _rand; Alternatively, you could also specify a midpoint in order to get a realisation of a Gaussian distributed random parameter (i.e. a random number extracted from a Gaussian distribution 😐) , centered (its mean) at the midpoint. An example of that would look like (using the same "function" as above) // I assume this is a function so I get the passed parameters params[["_min", 0, [0]], // Minimum of the range ["_max", 100, [0]], // Maximum of the range ["_mid", 75, [0]]]; // Midpoint of the range // Calculate random number private _rand = min + random[min, mid, max + 1]; // Return the number _rand; For more information please have a look at the comments of the respective BIKI page. The first one by Hcpookie regarding getting whole numbers and how each way to do so will affect the resulting distribution and the second about rough distribution numbers on a range [0, 9] from a Gaussian distribution (second code snippet above). One more comment to make here is that, since we are not provided any information on how these numbers are generated we can't be sure about the exact underlying distribution. For example, in many programming languages the "rand()" function provides quasi-random numbers but the higher numbers have higher probabilities (due to implementation specifics of course). The same may, or may not apply here too, but in my opinion (I haven't used the random command extensively though), the provided implementation is more than adequate for game scripting purposes. So, unless you seek to get a "mathematically correct" distribution I believe that random will be more than enough for any other purpose. Hope this helps somehow 😐.
  13. ZaellixA

    MK6 Mortar disappears

    Yes. You can use removeFromRemainsCollector, or you could just possibly check whether it is in the garbage/remains collector with isInRemainsCollector. See the following snippet as an example, where I assume the mortar object is valid in the scope the snippet will be called and it is called _mortar. if (isInRemainsCollector _mortar) then { systemChat "Mortar is set to be collected"; removeFromRemainsCollector _mortar; systemChat "Mortar is not to be collected anymore"; }; Of course you could skip all the systemChats but I believe you should at least have one in the if-statement's scope to see whether it was called or not (or you can just print the result of isInRemainsCollector command). Please let us know if this worked for you or not.
  14. ZaellixA

    MK6 Mortar disappears

    As Harzach mentioned in their post, maybe the garbage collector, which I believe is on by default, deleted it. For more information on the garbage collector you can have a look at the BIKI under the section Corpse & Wreck Management. If you need further assistance (for example a demo description.ext file showcasing a possible solution) please don't hesitate to post again. ---------------------------------------------------------------------------------- EDIT ---------------------------------------------------------------------------------- You could also have a look at this post in the forums.
  15. If _unit is defined then what you suggest should have the same results. Additionally, this is "valid" only in the init box of an object/unit.
  16. Could you post a demo mission that replicates just that? This way other people would be able to test your exact setup.
  17. ZaellixA

    Cool feature in Western Sahara

    ABSOLUTELY CORRECT... Thanks a bunch @mrcurry. I haven't scripted for quite some time and don't have a PC to test all the scripts I provide here. This has made me too rusty lately as it seems. On top of that I didn't pay too much attention to the BIKI, which I should start doing more systematically if I would like to provide some feasible solutions to people seeking help around here. Thanks a lot for the correction and @dashiellcote I am sorry for the extra effort (and possibly frustration) I put you in 😞... Glad it is sorted now and it wasn't something very complicated to work around. 🙂
  18. ZaellixA

    Cool feature in Western Sahara

    Well, I haven't really used this specific event handler but from my (maybe limited) understanding it shouldn't be that different from what you already have. This could possibly look like /* * Most probably this is best added in init.sqf in Singleplayer. */ player addMissionEventHandler ["TeamSwitch", { private _newUnit = _this select 1; (group _newUnit) selectLeader _newUnit; }]; Effectively, what I have done here is replace the player with the passed argument of _newUnit which is the unit you are "transferring" to. Since the new unit and the unit of the player is effectively the same unit (supposedly this event handler is triggered after the transfer to the new unit) you could possibly just use the same line of code you have used in your code and make it look like /* * Most probably this is best added in init.sqf in Singleplayer. */ player addMissionEventHandler ["TeamSwitch", { (group player) selectLeader player; }]; I believe the first one is safer because I am not sure whether the event handler is triggered after the change has happened or before. Thus, if you use the passed argument of the new unit to appoint the new team leader you will "always" be safe and sure that this unit, which you will be taking control of, will become the leader. And, since the overhead of getting the passed argument (_this select 1) into a variable is minimal, I strongly suggest the first snippet. Please do keep in mind though that the presented code is not tested and should be treated with caution. Don't hesitate to send back if you need more help, further refinement or anything else. And please, for the sake of future reference, let us know if this worked for you or not.
  19. Yeah but I mean, what exactly is '4' used for? Does it have a specific meaning, or it is just a number that "people have agreed" to mean something specific?
  20. In the documentation it seems like two numbers are used to "emulate" the OK and Cancel buttons. Do you care to elaborate on the use of 4 as an exit code in this case?
  21. Although I haven't tested it, a though would be to try to ask the AI to move further away from the supply box but on the opposite side of it. The thought is that in this way it would hopefully try to move on a straight line, thus ending up being closer to the supply box. This should be the last step of the whole process as you first have to find what the position of the AI is when it "completes" the waypoint and then ask it to move towards the box. This last step could potentially look like the following /* * I assume the following variables are valid * _unit: The AI * _box: The supply box */ // Calculate the unit vector pointing from the unit towards the box private _uVec = (getPos _unit) vectorFromTo (getPos _box); // Calculate coordinates of the new waypoint private _dist = _unit distance _box; // The distance between the unit and the box _dist = _dist - 1; // Subtract one from the distance to make the new waypoint (dist - 1) away from the box private _newCoords = _uVec apply {_x * _dist}; // Scale the unit vector // Add the new waypoint which is (dist - 1) meters away from the box on the opposite side (in respect // to the unit's position) [using your own code for this private _wp = _grp addWaypoint [_targetCache vectorAdd _newCoords, -1]; // ADD THE VECTOR TO THE COORDINATES OF THE CACHE _wp setWaypointType "MOVE"; _wp setWaypointStatements ["true", "{[group this] call soldierReload;"]; Of course, this is just a thought. The AI may decide that the box is an obstacle and attempt to go around it. The worst case scenario is for the AI to decide differently every time :|...I believe that this is highly possible, otherwise Harzach wouldn't have given up on AI some years ago ;P. Nevertheless, please note that this code is not tested and should be treated with caution and let us know if you managed to find a solution or workaround (for future reference).
  22. I believe Harzach has pointed to the right way (maybe there's more than just one right way though). You could possibly use "Reloaded" event handler to get the current magazine of the unit on reload and then use command "magazines" to get the total amount of such magazines left to the unit. This could possibly look like /* Add the event handler (I assume the unit is in a variable called * "_unit" but you could very well use "this" if code is placed in * the unit's init field. */ _unit addEventHandler["Reloaded", { // Get the new mag class private _newMag = (_this select 3) select 0; // Get the count of this type of magazines the unit has // (excluding the currently loaded one) private _nMags = {_x isEqualTo _newMag} count (magazines _unit); // Now set the condition to send the unit to the ammo cache // (using Harzach's example of one magazine here) if (_nMags <= 1) then { // Using teleportation here for demonstration // I assume the cache is a named entity called "ammoCache_3" _unit setPos (getPos ammoCache_3); }; }]; You could very well one-line the calculation of the magazines left inside the condition of the if statement like if (({_x isEqualTo _newMag} count (magazines _unit)) <= 1) then { // Blah blah blah }; Or you could even one-line the whole thing which in my opinion makes things worse (unreadable or very-difficult-to-read code is not easily maintainable and the inclusion of a couple more temporary variables does not provide considerable overhead to avoid their use), but it could look like if (({_x isEqualTo ((_this select 3) select 0)} count (magazines _unit)) <= 1) then { // Blah blah blah }; Plus, this could potentially add some overhead due to the fact that, if the condition is left unoptimised (not sure if there's any optimisation being behind the scenes to the code being executed from an .sqf), there's a possibility that the selection of the first element of the third element of _this could be using some extra cpu cycles (if optimisation kicks in somehow it will most probably be placed in a temporary variable but we don't know that) every time you test against each magazine of the unit. Of course all this gibbering is only to try to move people to the direction of clean coding and it doesn't mean that one of the above snippets would destroy fps and ruin your gaming experience while the other is the way to go. Anyway, I hope the snippet(s) above help somehow to point you towards a possible solution to your problem. Please do keep in mind that the code presented here is not tested and should be treated with caution. Don't use it without testing as it may need some corrections, refinements and/or may not achieve what you want to achieve. Finally, please let us know if you require more help or if this is solves your problem. If not please do provide your solution for the benefit of people that either have the same issue or will do so in the future.
  23. ZaellixA

    Which mod is this?

    First of all, the image you have attached is not visible, at least on my laptop. This may be am issue on my side though. Next, it would be quite beneficial to provide an answer here since you found one. This could possibly benefit other users in the future.
  24. Would you care to provide your solution so that others may benefit in the future from it?
  25. If you have place the code in the init box then you shouldn't worry because the code in the init box is run for each and every player joining the game. This means that all players will have an action added to their menu that will allow them to "roll the dice". You could possibly use hideObject or even better hideObjectGlobal command(s). The only thing is that the latter should be called on the server. To be honest, I am not very fond of creating a lot of objects and then moving them around when needed. It seems like an abuse of resources, which of course is not necessarily true, especially if the number of objects you create is kept to a decent value and even more, if you allow dynamic simulation of the objects. Nevertheless, it seems to me a "better practice" to create something when you need it and destroy it when it's "lifetime" has ended (or let the garbage collector do it for you if this is acceptable). Please, don't get me wrong on that, Joe98's solution works just find and most probably with 20 or so different objects, most probably, won't make a noticable difference on the gameplay/framerate. It's just my opinion that I express here and it's up to you (and everyone else on the forums) to choose their preferred style.
×