Jump to content


  • Content count

  • Joined

  • Last visited

  • Medals

Community Reputation

90 Excellent


About Muzzleflash

  • Rank
    First Sergeant


  • Interests
    Little of everything
  1. Get objectID of players Map (MP)

    This is over in the more advanced scripting arena. I don't believe there is any such object id for the map item. Simply put you just have a generic map item in your inventory, no id, all maps are the same. So one basic approach would be to: whenever a player drops a map, 1. Store all marker info on the dropped container (even if you drop something on the ground a new "container" is made) 2. Remove all markers from the players "map screen" Then when someone takes from the container, you check if they take a map, if so: 1. Add all the markers to the takers "map screen" 2. Remove the data from the previous container Even then, this is not foolproof. Now the latter player have two maps. What happens when he drops one of them? Then the second one? Which is his real map? Because, AFAIK the lack of object ids this gets you into trouble. But the approach can work decently, it is the basic outline for how ACE detonators are implemented. First you should familiarize with the map commands, particularly, allMapMarkers and deleteMarkerLocal. Then you might want to check how ACE does it: https://github.com/acemod/ACE3/blob/master/addons/explosives/functions/fnc_onInventoryChanged.sqf
  2. Copying IP from the launcher

    Agree, you shouldn't need to, though the launcher has never let me connect to a server if the game was already running. Have to do the stupid copy entire server info, then paste it somewhere so I can manually extract the IP and port.
  3. Here is my offering: MY_fnc_EnemySpawnLocation = { params ["_closeToOneOf", "_minDist", "_maxDist", ["_objDist", 3]]; _maxDist = _maxDist max (_minDist + 200); // Avoid impossible / hard to find location private _badPos = [0, 0, 0]; private _pos = _badPos; // Construct blacklist circles private _blacklist = _closeToOneOf apply { [getPos _x, [_minDist, _minDist, 0, false]] }; // Sigh... private _blacklist2 = _blacklist apply { [_x select 0] + (_x select 1) }; // Keep trying while {_pos distance _badPos < 1} do { _pos = [ selectRandom _closeToOneOf, _minDist, _maxDist, _objDist, 0, // No water 1, // Max Grad 0, // Don't have to be shore _blacklist, [_badPos, _badPos] ] call BIS_fnc_findSafePos; // BIS_fnc_findSafePos only applies blackList in initial phases might still find a bad location if (_blacklist2 findIf {_pos inArea _x} >= 0) then { _pos = _badPos; }; }; _pos }; Here is example of usage: private _spawnPos = [[player1, player2], 1000, 1500] call MY_fnc_EnemySpawnLocation; Here is an image of me creating 1000 markers on the position returned with two "players". The red area is the minimum distance, and the blue marks the maximum distance. Note that in the overlap there are many more points. This is because regardless of which player it picks, the overlapped area has a chance. If it is intended to spawn AI near players, this might in fact be an advantage since it is more likely they will spawn, still out of range, but near more players. Though if this is not desired, it is possible to workaround by using another approach. Depending on conditions, this ran take some time, e.g. if little land available for spawning, say on a small island like Utes above, so you might want to run this in a scheduled environment (eg. using spawn).
  4. I don't understand why you need to bother with the Eden IDs at all. Do you not care about ingame/Zeus spawned entities? Seems like you just want save/load functionality? Either you are: - Starting fresh mission: On mission start synchronize (assign) ids with all mission objects - Loading mission: Delete everything present in the mission (that you would normally assign IDs) and recreate from database info instead. Minor things that have to be handled differently is for instance playable units which you do not delete. Then regardless of above, synchronize any future ingame changes, either continually, or some custom save action/button (if you trust the server won't crash) for potential future load.
  5. Sorry, but there are so many things wrong with that code snippet. First of all, you already left the event handler when you used spawn and there was nothing afterwards. Your calls are basically useless. Inside the addAction code, you call into a new scope just to leave it. You could just write _exit = true; , but it would still not work because the action script runs in a different context and thus cannot access the same _exit . In fact that variable is most likely not defined on the same computer as the one your action runs on. For the second call, the reason it seems to have no affect, is again because you call into a new scope, and then you exit that scope bringing you back to the original one. Can you describe what your intended goal is? It looks like you want players to be able to toggle a radio that is somehow controlled by the server?
  6. I updated the post above, since it was based upon a false assumption.
  7. You don't even need to remote call. At least according to BIKI you can add remote units. Some skilled SQF'ers on the Discord informed me the BIKI was wrong. The event handler only runs if the object/player is local. You need something like this: // for example in: initPlayerLocal.sqf params ["_player", "_didJIP"]; _player addEventHandler ["InventoryClosed", { ["PX_InventoryClosed", _this] call CBA_fnc_serverEvent; }]; And on the server you handle the event // for example in: initServer.sqf ["PX_InventoryClosed", { params ["_unit", "_container"]; // Do your stuff here. }] You are probably going to want to check the type of the _container, since the player can open inventory arbitrary. If the player opens inventory on nothing, or on stuff put on the ground, _container isKindOf "GroundWeaponHolder". Idea: maybe do as much processing as possible involving the _container on the player side before sending the event. Since you are closing a container, it might be a GroundWeaponHolder becoming empty, and thus it might have been deleted when the message get processed on the server.
  8. Event handlers are totally client side so you should be fine. I mean most object each has dozen of event handlers on anyway. But are you sure you cannot use InventoryClosed instead?
  9. Here is a full example of what I had it mind. // for example in init.sqf if (isServer) then { ["PX_ContainerClosed", { params ["_container", "_unit"]; // What you want to do on the server here // .... }] call CBA_fnc_addEventHandler; }; if (hasInterface) then { { _x addEventHandler ["ContainerClosed", { ["PX_ContainerClosed", _this] call CBA_fnc_serverEvent; }]; } forEach [MyContainer1, MyContainer2]; };
  10. Not sure what you mean? The wiki says the argument to addEventHandler can be global, in this case the container. But as the note says, it will only fire where the player opening it is local. So, I guess no, you have to addEventHandler on all player machines. Basically if (hasInterface)...
  11. It will only fire for the client opening the container. You can use remoteExecCall or CBA events to alert the server. Like: _this addEventHandler ["ContainerClosed", {["PX_ContainerClosed", _this] call CBA_fnc_serverEvent}];
  12. quick stringReplace

    I realized it was wasteful to add the replacement incrementally and then join by empty string. Instead I just join on the replace-string directly. This also works if replacement happens at the the start and end, since then empty strings are still added to the _parts array. I updated my function, and the benchmarks. It gave a tiny reduction, mostly visible on the 10-times search text, where it gave ~ 0.005 ms.
  13. quick stringReplace

    @PixeL_GaMMa I added your two new variants (I suffixed the second with '2'. PX_fnc_stringReplaceEx seems to perform well. The results are updated above. For the negative case, there is no reason why PX_fnc_stringReplaceEx should have different speed than mine, so we can safely assume the 0.001ms difference is noise (or the difference between == and isEqualTo).
  14. quick stringReplace

    This is my version. I tried to optimize for "predictable worst case performance", but it seems to run quite well. I updated the benchmark results I ran above to include it: MF_fnc_replaceInString = { params ["_str", "_find", "_replace"]; private _matchPos = _str find _find; if (_matchPos isEqualTo -1) exitWith {_str}; private _parts = []; private _len = count _find; while {_matchPos >= 0} do { _parts pushBack (_str select [0, _matchPos]); _str = _str select [_matchPos + _len]; _matchPos = _str find _find; }; _parts pushBack _str; _parts joinString _replace; };
  15. quick stringReplace

    To be honest, I don't think anyone has to beat it, since your solution is cheating and only works for properly for this particular input. Though you do admit you didn't test thoroughly. Put simply, splitString is not very useful here, and I suggest you read more carefully what it actually does. Examples: ["xxNOx is awesome, I love xxx!", "xxx", "Arma"] call GOM_fnc_replaceInString ==> "NOArma is awesome, I love Arma!" ["xxx is awesome, I love xxx!", "xx ", "Arma"] call GOM_fnc_replaceInString ==> "isArmaawesome,ArmaIArmaloveArma!" ["x x x is awesome, I love xxx!", "xxx", "Arma"] call GOM_fnc_replaceInString ==> " Arma Arma is awesome, I love Arma!" ["xxx is awesome, I love xxx!", "love", "Arma"] call GOM_fnc_replaceInString ==> "xxx is awArmasArmamArma, I Arma xxx!" ["xxx is awesome, I love xxx!", "awesome", "Arma"] call GOM_fnc_replaceInString ==> "xxx iArma Arma, I lArmavArma xxx!"