Jump to content

Muzzleflash

Member
  • Content Count

    1001
  • Joined

  • Last visited

  • Medals

Everything posted by Muzzleflash

  1. 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?
  2. 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]; };
  3. 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)...
  4. 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}];
  5. Muzzleflash

    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.
  6. Muzzleflash

    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).
  7. Muzzleflash

    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; };
  8. Muzzleflash

    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!"
  9. Muzzleflash

    quick stringReplace

    The average seems stable most of the benchmark runs, but sometimes they would just double when I ran them. The following is median of 3 (10000-iterations) runs (ludicrous runs excluded). PX_fnc_stringReplace : ~0.0123 ms PX_fnc_stringReplaceEx : ~0.0115 ms PX_fnc_stringReplace2 : ~0.0149 ms GOM_fnc_replaceInString : ~0.0144 ms TER_fnc_editString : ~0.0174 ms MF_fnc_replaceInString : ~0.0109 ms But there is more to benchmarking than just trying with fixed arguments. Like, what if no matches? Or what if longer input. I ten-doubled the input text (first argument) so it basically is of a single paragraph length and got these numbers then (again median of 3 runs). Now the disparity us much larger. This can be important if you replacing in long texts: PX_fnc_stringReplace : ~0.0855 ms PX_fnc_stringReplaceEx : ~0.0768 ms PX_fnc_stringReplace2 : ~0.0810 ms GOM_fnc_replaceInString : ~0.1486 ms TER_fnc_editString : ~0.8496 ms MF_fnc_replaceInString : ~0.0623 ms These are the median of 3 runs if I change the search text to 'Schwifty' (e.g. not match), still 10 times input length: PX_fnc_stringReplace : ~0.0056 ms PX_fnc_stringReplaceEx : ~0.0037 ms PX_fnc_stringReplace2 : ~0.0061 ms GOM_fnc_replaceInString : ~0.0037 ms TER_fnc_editString : ~0.0045 ms MF_fnc_replaceInString : ~0.0036 ms Final comment, for GOM_fnc_replaceInString I added 'private' before '_pos = ...', since this should actually be done to avoid messing up outer scopes, which might cause frustrating bugs for callers. But I do not think this invalidates the test, since it both makes the code safer, and also in fact makes GOM_fnc_replaceInString run a tiny bit faster.
  10. Muzzleflash

    quick stringReplace

    Can you guys give a real world example of when you need to replace strings? Can only come up with examples where you get data from an external source you do not control.
  11. _array = _array arrayIntersect _array;
  12. One option is to use this approach: // Run on server addMissionEventHandler ["EntityKilled", { params ["_killed", "_killer", "_instigator"]; // Was it an artillery guy that killed the person? if ([arty_guy1, arty_guy2, arty_guy3] find _instigator != -1) then { // Determine proper _player to receive credit private _player = player24; if (!isNull _player) then { private _toAdd = [1, -1] select (side player == side _killed); _player addPlayerScores [_toAdd, 0, 0, 0, _toAdd]; }; }; }];
  13. Since you use CBA here is the proper way to do it. You need something like this in your description.ext file: class CfgFunctions { class FLY // flymaker { class Equipment { class ReplaceEquipment { file = "replaceEquipment.sqf"; }; }; }; }; class Extended_Init_EventHandlers { class CAManBase { class ReplaceEquipment { init = "_this call FLY_fnc_ReplaceEquipment;"; }; }; }; Then in your script file, in this example it must be placed in the root of your mission folder and named 'replaceEquipment.sqf', you process each unit. The file will now run for all humanoids, regardless of how they are spawned in: params ["_unit"]; // Do what you want here. I have an example here: // Only run local to avoid duplicate stuff and ensure we can use local-only commands. if (!local _unit) exitWith {}; // Let's not mess with human players if (isPlayer _unit) exitWith {}; // Add the Satchel charge _unit addMagazine "SatchelCharge_Remote_Mag"; // Switch the weapon _unit removeWeapon (primaryWeapon _unit); _unit addWeapon "LMG_Mk200_F"; // Adjust what you need. Don't forget to give new ammo. Recommend you do that before giving the weapon.
  14. ID 2 is always the server. If you are running a dedicated server then the server don't have a player object so it is always null -- like in my example above. If you are running a hosted server you should have a player object.
  15. On that last comment, that is the same thing I said earlier. Anyway in order to test it, I modified to also send the message to the server and back again to myself, and I logged the values passed to CHAB_fnc_jipcam. The leftmost ID is what the player/server machine got of values. ID (3) sees, '_joinedPlayer' has value 'B Alpha 1-2:1 (Muzzleflash)' ID (3) sees, '_joinedUID' has value '76561234589382009' ID (3) sees, '_localId' has value '3' ID (3) sees, '_local' has value 'B Alpha 1-2:1 (Muzzleflash)' ID (2) sees, '_joinedPlayer' has value 'B Alpha 1-2:1 (Muzzleflash) REMOTE' ID (2) sees, '_joinedUID' has value '76561234589382009' ID (2) sees, '_localId' has value '2' ID (2) sees, '_local' has value '<NULL-object>' In this case ID 3 is me joining and ID 2 is the server. But suppose instead, another player was already joined when I connected, and the only he got the message, then he would see something like: ID (7) sees, '_joinedPlayer' has value 'B Alpha 1-2:1 (Muzzleflash)' ID (7) sees, '_joinedUID' has value '76561234589382009' ID (7) sees, '_localId' has value '7' ID (7) sees, '_local' has value 'B Alpha 1-3:2 (Leeroy Jenkins)'
  16. Dunno, the getPlayerUID command is listed as being possibly unreliable when executed where the object is not local. So my suggestion would be did. First I don't believe you need the wait since initPlayerLocal.sqf is not run before the player object is ready. To ensure the UID is properly collected gather it from the joining player's machine, and since you can't rely on it find the player object, send it manually too: if (didJIP) then { [player, getPlayerUID player] remoteExecCall ["CHAB_fnc_jipcam",[-2,-(clientOwner)],false]; }; And CHAB_fnc_jipcam: params ["_joinedPlayer", "_joinedUID"]; // Remote player unit and remote unit UID private _localId = clientOwner; // Local machine ID private _local = player; // Local player
  17. I don't know how it is set up now - I can only assume the line you just mentioned is above the very first part you showed. So you are going to have to show the entire script to debug. Else, I can only say the player command itself works fine.
  18. Correct. The commander 'player' only returns the object the player sitting on that machine is controlling. So a dedicated server does not have a player object, in fact no machine at all has a player object until someone connects and takes a slot. Then only that connecting player now get a player object.
  19. The text may vary, but it is supposed to say something different than <NULL...> .
  20. Are you running a dedicated server? Have you placed any player objects in the mission?
  21. You example demonstrates that there is no player object on the machine you ran it on. Thus the <NULL OBJECT> and the command getPlayerUID failing to get the proper result.
  22. Also, you send the uid of the (assuming joining) player as argument. Then you iterate all players to get the player object. Just send the player object instead, and use it to get the uid. if (didJIP) then { [player] remoteExecCall ["CHAB_fnc_jipcam",[-2,-(clientOwner)],false]; }; And CHAB_fnc_jipcam: params ["_player"]; // Remote player unit private _uid = getPlayerUID _player; // Remote unit UID private _localId = clientOwner; // Local machine ID private _local = player; // Local player
×