Jump to content

mrcurry

Member
  • Content Count

    615
  • Joined

  • Last visited

  • Medals

Everything posted by mrcurry

  1. Assuming _car and _module are defined elsewhere this will definitely work: _car in synchronizedObjects _module; This might not work: _module in synchronizedObjects _car; If I remember correctly this is because only "smart" objects (logics, units and triggers) retain a list of synchronizedObjects. I recommend testing to be sure 🙂
  2. I imagine it has to do with which parameters you generate the texture for the PiP render. Show how you apply the texture.
  3. 1. A vehicle's varname being "xyz" doesn't mean that the variable xyz automatically points to that object (xyz won't even be defined). vehicleVarName has no functional connection to actual variables. That they are similar when entered in the editor is just by convention or for 'ease of use'. If you want to replicate the way variable names from the editor work you need to both execute setVehicleVarName and assign the reference to the variable: _obj setVehicleVarName "MyCar1"; MyCar1 = _obj; Or if you want to be extra explicit (these are both equivalent): _obj setVehicleVarName "MyCar1"; missionNamespace setVariable ["MyCar1", _obj]; 2. That is one appropriate way to get the mission-global variable called MyCar1. For the same reason as above you _obj = missionNamespace getVariable "MyCar1"; is equally equivalent to _obj = MyCar1; unless the latter is explicitly executed in another namespace for example using 'with'. If you want the vehicleVarName you use the command by the same name. As for identifying the vehicle the respawn module passes the old and new vehicle to code in the statement executed on each respawn so using that you can easily get the correct reference without resorting to global variables if that's what you wish.
  4. Recursive calls into a new thread to simulate a loop, now I've surely seen it all... Considering that spawn has to create a new scope and register in the scheduler and then wait to be executed, the second approach should be faster. I can't think of a situation where the first option is faster but you could just test it by measuring diag_tickTime, just make sure in your first example to take the final measurement when the last thread finishes. Personally I would never use the first option unless I have to, mostly cause I find it's less readable and managing variables across multiple iterations would be a pain.
  5. The save* commands pushes the data to the file. BI probably only pushes changed data but let's assume otherwise for a worst case scenario. If the game exits cleanly it also commits the changes to disk. File operations are slow in a computing sense but from human perspective they're still quite fast. My guess is that unless your pushing megabytes of data with each saveProfilenamespace call you don't need to worry about perf too much. Could do some quick testing. Each save call likely carries with it an overhead for opening and closing the filestream so avoid doing it every frame and preferably batch save as much data as is reasonable. As for when it's useful to save well that depends on your requirements don't it? Consider what data you're saving and either save after each update or, if it's worth the effort, implement an autosave feature. Sometimes you can just fallback on default data. If the data is likely to change alot and/or the impact of its loss is major then save often. Example: player position, player gear, time of day (hour) If the data is fairly static and/or is unimportant then you can get away with losing it after a crash. Example: time of day ( minute / second ) We can't predict a crash but can assume they will happen, build protections against them.
  6. As @Chuggacharles mentioned serverNamespace will work, but only as long as the server runs, if a crash or restart happens w/e is stored in that namespace will be lost. If you want to be able to handle that you could store your data on the server using missionProfileNamespace instead. Just remember to call saveMissionProfileNamespace when you've done your updates. Drawback for this approach is that any reset needs to be done in the code. Yes
  7. https://community.bistudio.com/wiki/Arma_3:_Loading_Screens
  8. I recommend checking out the syntax pages on the biki again 😉 SQF does not have all the neat features many modern languages do.
  9. mrcurry

    execVM for all players

    To expand on Schatten's answer a little: A good read for understanding locality can be found in the follow link but you can save that for later: https://community.bistudio.com/wiki/Multiplayer_Scripting#Locality The main takeaway is that any multiplayer session works by multiple machines essentially running their own "version" of the events of the game. The server is master and there's a fair amount of synching for every computer to share the same state. At the same time we don't want the entire state of the game to be shared e.g. pressing Escape on one player's computer should not open the pause menu on all other players' computers. This is why script commands can have local/global arguments (denoted LA/GA respectively) and local/global effect (LE/GE). So createDiarySubject is an LE command, you can see this on the BIKI: https://community.bistudio.com/wiki/createDiarySubject That means what you are currently doing is adding the diary subject on to all players but only on the computer that executes the code, this is not synced to other computers. To send code to other computers we use remoteExec. // fn_init.sqf if( isServer ) // To avoid duplicates we make sure only machine executes the code, in this example the server { // Instead of looping and sending the request in multiple messages we send them in 1 call, more efficient use of network resorces ["Hello", "Evertbody"] remoteExec ["TAG_fnc_addDiarySubject"]; } // Instead of script.sqf make it a function, avoids compiling during runtime. // fn_addDiarySubject.sqf if( hasInterface ) then { // Filter out dedicated server and headless clients params ["_subject", "_displayName", ["_picture", ""]]; player createDiarySubject [ _subject, _displayName, _picture ]; // You could also just pass the parameters directly in but that is less readable: // player createDiarySubject _this; };
  10. mrcurry

    Addtional map legend markers

    Only a mod can add things to CfgMarkers and CfgMarkerClasses. The only way you can get clients to download image data from the server is to include it in the mission. You can draw icons on the map using drawIcon, note that these do not function like regular markers have to be manually managed. See the examples in the linked BIKI page.
  11. Let me clarify. The missionNamespace variable flak_shrapnels isn't used that way, because it's overriden with Nothing at all places shown. If you mean you are using the _unit namespace variable flak_shrapnels to select between the effects you can just remove the redundant code, and you should. The reason for this is simple: Getting rid of the publicVariable calls. publicVariable only broadcasts the variable to the network, nothing else. It does so reliably (resending info if need be) even if the variable broadcast is nil or Nothing. This means you are currently generating network traffic for something that doesn't need it. With just one or a few object this isn't much but if someone places a lot of your vehicles on the map it's gonna add up. On top of that the broadcast goes to all clients so larger the player counts is the worse it's going to affect the network. Here's the changes required to make it not waste network resources, if you don't wanna do it all just get rid of all the publicVariable calls... Well I guess it depends what standard you hold yourself and your code too. SQS is considered obsolete these days. But you say the flak88cam.sqs works... so when the problem occurs: What kind of behaviour do you expect? What kind of behaviour do you get?
  12. Tbh that is something for it's own thread 'cause best practices for "finding places to put things" is like a whole thing... I also find that "finding"-code is often heavily connected with other features so giving you something that "just works" is no small ask. What works for my project might not work for yours. I don't want to bog down this thread with unrelated detailed discussion (it's already long as it is) so here's just some ideas to apply to your design. If you want more specific help create a new thread with your ideas, terrain and current code, or send 'em through a PM. First off - There are many ways to skin this particular cat. An automated approach is cool and all but sometimes just manually doing it can get the job done, and better too. Maybe when a marker is selected you select from a list of preselected positions instead. Ask yourself: Does finding the flat space with code improve your player's experience or are you just being lazy? 😉 I mainly use the same tools you mentioned, I currently prefer BIS_fnc_findSafePos. Finding the right parameters for the search can be hard but don't get discouraged, play around with the settings and test a lot, especially in places where success is dubious. Remember: There's nothing wrong with searching multiple times with different parameters if the search fails. Start strict and loosen up. Figure out which compositions are required to spawn and which (if any) can be ignored if no suitable position is found. Define your needs clearly. Use a Solver / Spawner combo, the idea goes like this: The mission logic runs the Solver to find the positions around a given spot (e.g. a marker). The Solver spawns nothing, only returns a solution: a bunch of valid positions to place stuff at. The mission logic then checks the returned solution: Solution is valid - Run the Spawner which does the actual spawning of your stuff. Solution is invalid - Invalidate the selected spot (marker) and select a new one then repeat the process from the beginning. If your composition is often colliding with terrain objects: ask yourself if you need those map objects or can they be safely hidden without detriment to the player experience? hideObjectGlobal is your friend here. Players won't miss a tree or a rock but an important landmark might be noticed, take this into account in your solver. Prefect is the enemy of good. This is especially true for this.
  13. Couple of things: When asking for help use the code brackets <> button at the top of your reply editor to wrap your code inside one of these: /* Your code here */ Makes everybody happier. Remember to change from HTML to C Languages. You are using this in a few places: flak_shrapnels = _unit setvariable ["flak_shrapnels",false]; publicVariable "flak_shrapnels"; I don't think this is the cause of your issues but it doesn't do anything useful. setVariable returns Nothing which means flak_shrapnels always contains Nothing and the publicVariable call sends Nothing over the net (though probably still generates traffic) If you want the value of flak_shrapnels to be the same value on all clients make sure you assign a useful value. Just keep in mind that when you start sending global data over the network it can override the state of your scripts on other machines, in your case it seems odd to have flak_shrapnels be equal on all clients so the use of publicVariable is probably incorrect. You aren't giving us the full picture either, when the loop finds a target you're exec-ing a .sqs (which is the older format btw), what are the contents of "\88mm\scripts\flak88cam.sqs"?
  14. You have just got a lesson in why you don't just copy-paste forum plain text straight into the game 🙂 This is what a copy of it looks like with a proper code editor: I've cleaned it up in the previous post but to be safe type it in from scratch yourself instead. The code works, just tested it myself.
  15. Note the brackets around MyCar, those represents an array (a list), which in the example only contains w/e MyCar points to. addCuratorEditableObjects takes an array of objects as it's first right hand parameter. That means we can't feed it the group reference directly, instead we have to convert the units of the group into an array. Luckily we have a command for that: units The group is delivered to us through the passed arguments These are accessible using param, params or directly from the "magic" variable _this. So to put it all together: Zeus1 addCuratorEditableObjects [ units param [0], true ];
  16. mrcurry

    Squad Rallypoint System

    Scanning through this unwieldy beast of the past I'd say it likely goes into a script called by an addAction that is added to the respective leaders. It also requires the relevant leaders to be given variable names like mentioned above and the respawn mode for the mission to be set to use the BIS respawn template "MenuPosition".
  17. Instead of relying on placed objects you could also have the unit remember where it came from by using setVariable/getVariable appropriately. Example: Coming to a browser near you later this evening! // Before doing the move _unit setVariable ["spot", getPos _unit]; // Do your move here... // When you want them to return private _position = _unit getVariable "spot"; // Make your unit move to _position
  18. Replace side with BLUFOR or whichever given side you wish to get units for.
  19. units side select { !isPlayer _x } joinSilent group player
  20. The naive solution would be to just iterate over units BLUFOR and compare distances. To save on perf we can use distanceSqr to compare. Assuming the code runs rarely ( as in not several times per frame ) this should be fine even with a lot of units: private _nearest = objNull; private _minDistance = 1e39; // infinity { if ( !isPlayer _x ) then { private _d = _x distanceSqr player; if( _d < _minDistance ) then { _nearest = _x; _minDistance = _d; }; }; } forEach units BLUFOR; // _nearest now contains the closest blufor AI [_nearest] joinSilent group player;
  21. Have you by chance set your server up so only approved commands can be remoted and forgot to allow systemChat?
  22. Obvious bot is obvious. Reported. Edit: Reported it, not you ofc 🙂 obvious semantics are not so obvious.
  23. mrcurry

    Get POS Set POS

    Positions in arma 3 are just sets of 2 or 3 numbers: [ X, Y ] or [ X, Y, Z ] Each number represents how far from the origin you have to travel parallel to one of the three major axis, X (runs east/west), Y (runs north/south) and Z (up/down). The origin is always the bottom left corner of the map. Adding 20 to the x-coordinate of a position is the same as walking 20 meters east. Subtraction is just adding in the opposite direction so that moves us 20 m west. The same idea also applies to y and z. So in @Joe98's example you walk -20 then another random 0 to -80 meters. To get a better sense of this you can use the position indicator in the editor ( bottom left ) and move the cursor slowly around the map and watch what happens with the numbers. Just change min and max to 0 and 5, this will give you a position 0 to 5 meters from the helo. Assign that to a variable and use the variable in your setPos statement.
  24. mrcurry

    Get POS Set POS

    The area covered is a square aligned to the xy-plane (east-west, north-south), this is 'cause you are just adding a random value to each coordinate. If you want a circular area then get it with the alternative syntax for getPos: origin getPos [distance, heading] Example with min and max distance: min = 5; max = 20; helo getPos [ min + random (max - min), random 360 ]; Edit: The above will not be uniform in its distribution however and points will tend towards the center. For a more true random distribution use: helo getPos [ min + (max - min) * sqrt random 1, random 360 ];
  25. That would be my guess, the lines the error messages are referring to are syntactically correct and should work. Try just manually deleting everything that seems empty and adding your own spaces, tabs and newlines. It may just be easier to rewrite the offending sections from scratch.
×