Jump to content

sxp2high

Member
  • Content Count

    783
  • Joined

  • Last visited

  • Medals

  • Medals

Everything posted by sxp2high

  1. Yea, it's always send to the server first, to decide. (publicVariableServer) BIS_fnc_MP_packet = [0,_params,_functionName,_target,_isPersistent,_isCall]; publicvariableserver "BIS_fnc_MP_packet"; If server is receiver, nothing is send across the network. If one specific client is receiver it's redistributed via publicVariableClient. If all clients are receiver it's redistributed via publicVariable. if (_ownerID < 0) then { //--- Everyone publicvariable "BIS_fnc_MP_packet"; } else { if (_ownerID != _serverID) then { //--- Client _ownerID publicvariableclient "BIS_fnc_MP_packet"; }; };
  2. sxp2high

    Game Logic and JIP

    Alright I looked at it. But as I see it you're using Extended_PreInit_EventHandlers, not a game logic? I never used Extended_PreInit_EventHandlers within a mission, so I'm not sure how it works. Looks like it's probably not JIP compatible. You should use a game logic instead, as your thread title suggests, and use its init line. This, from an init line, will definitely work for JIP: call (compile preprocessFileLineNumbers "tb3\preInit.sqf"); I'm using that method all the time. :)
  3. sxp2high

    Game Logic and JIP

    Okay, need a bit more info then. What is the game logic doing?
  4. Not very nice looking, but this should work: call (compile (format['%1 = "I_UAV_02_F" createvehicle (getmarkerPos "center");', _objectName])); Or just: call (compile (format['%1 = %2;', _objectName, _vehicle])); Or: missionNamespace setVariable [_objectName, _vehicle]; missionNamespace
  5. sxp2high

    Game Logic and JIP

    Add this to the very top of your init.sqf (and all other scripts that run before): waitUntil {(isDedicated) || !(isNull player)};
  6. Oops, my bad... cutText is correct. :) Glad it works. With AI it should be easier, you could just teleport them away while respawn is disabled.
  7. Oh, right, the spectator should be terminated properly. This should do it: // Register layer once _layer = ["specator_layer"] call BIS_fnc_rscLayer; // Start spectator _layer cutRsc ["RscSpectator", "PLAIN"]; // Stop spectator _layer cutRsc ["", "PLAIN"];
  8. Hello :) Haven't tested this, so it might not work as is. Maybe I overlooked some things too. But something like this should do it. Have a look and play around with it :) // Use this variable to control respawn respawn_disabled = false; [] spawn { // Some variables that control spectator options RscSpectator_allowFreeCam = true; // Free cam RscSpectator_hints = [true,true,true]; // Shows the controls as hint // Get initial respawn time _respawnTime = playerRespawnTime; // Main loop while {true} do { // Wait until respawn disabled waitUntil {respawn_disabled}; // "Disable" actual respawn setPlayerRespawnTime 9999; // Wait until respawn is enabled again or player died waitUntil {!(respawn_disabled) || !(alive player)}; // if respawn disabled AND player dead if (respawn_disabled && !(alive player)) then { // Maybe a little sleep so its not switching to spectator immediatly sleep 5; // Disable post processing effects for spectator (Fatigue blur and such) BIS_fnc_feedback_allowPP = false; // Start spectator cutRsc ["RscSpectator", "PLAIN"]; // Wait until respawn is enabled again waitUntil {!(respawn_disabled)}; // Re-enable post processing effects BIS_fnc_feedback_allowPP = true; // Set original respawn time setPlayerRespawnTime _respawnTime; //Respawn the player forceRespawn player; } else { // Set original respawn time setPlayerRespawnTime _respawnTime; }; }; };
  9. sxp2high

    Wiggum's Coop missions (no respawn)

    We tried Negotiations Failed on Tuesday, great mission. I was about to suggest to make the no-Fatigue optional, but you're already on it I see. :) We noticed right away, since we're using Dslyecxi's Stamina Bar. The mission was fun and well made. We also failed to rescue the hostage though, poor guy. :( At least our entire team made it out alive. Will definitely try it again soon. One little suggestion regarding gameplay: Thanks and keep it up, very good no-respawn missions!
  10. spawn creates a new thread/vm (virtual machine) call executes code within the same thread call { sleep 5; }; hint "This will be shown after 5 sec."; [] spawn { sleep 5; }; hint "This will be shown instantly."; Local variables are also to be considered. That's why local variables in called code should be made private. _test = 123; call { hint format[" %1", _test]; }; // Will display 123 hint format[" %1", _test]; // Will display 123 _test = 123; call { private ["_test"]; _test = 456; hint format[" %1", _test]; // Will display 456 }; hint format[" %1", _test]; // Will display 123 _test = 123; [] spawn { _test = 456; hint format[" %1", _test]; // Will display 456 }; hint format[" %1", _test]; // Will display 123 Has been asked recently here.
  11. sxp2high

    Script Help

    Like this? waituntil {((vehicle player != player) && (vehicle player iskindof "Helicopter") && !(vehicle player iskindof "Steerable_Parachute_F"));}; Not 100% sure about the classname.
  12. Well, good decision, I wouldn't like them either. addAction should be avoided, especially for minor things like this. Action menu is cumbersome and cluttered enough as it is :) Probably best to use a button press to toggle them on and off. First you need to change the code, so all arrows are added to an array, so you can refer to them: if (isServer) then { player_arrows = []; publicVariable "player_arrows"; // Create array on the server }; if (!isDedicated) then { waitUntil {!(isNil "player_arrows")}; // wait for the server _playerarrow = createVehicle ["Sign_Arrow_F", (getPosATL (vehicle player)), [], 0, "NONE"]; _playerarrow attachTo [player, [0,-0.5,3]]; player_arrows set [(count player_arrows), _playerarrow]; publicVariable "player_arrows"; // Add arrow to the array and publicize while {true} do { _vehicle = (vehicle player); waitUntil {sleep 1; ((vehicle player) != _vehicle) || !(alive player)}; // Wait for vehicle change OR player not alive deTach _playerarrow; // Not sure if necessary if (!(alive player)) then { waitUntil {(alive player)}; }; // If player is dead, wait for respawn _playerarrow attachTo [(vehicle player), [0,-0.5,3]]; }; }; Then add a displayEventHandler for the button: [] spawn { // Function for toggle fnc_toggleArrows = { if (isNil "toggleArrows") then { toggleArrows = true; { _x hideObject true; } forEach player_arrows; // Hide all arrows } else { toggleArrows = nil; { _x hideObject false; } forEach player_arrows; // UN-hide all arrows }; }; waituntil {!(isNull (finddisplay 46))}; // needed for displayeventhandlers sleep 0.1; // sometimes they dont get added without a tiny sleep // Add keyhandler _keyHandlerUp = (findDisplay 46) displayAddEventHandler ["KeyUp", "if ((_this select 1) == 23) then { [] call fnc_toggleArrows; };"]; hint "Press I to toggle player markers."; }; Key would be i in this example. Which is 23. _keyHandlerUp = (findDisplay 46) displayAddEventHandler ["KeyUp", "if ((_this select 1) == [b][color="#FF0000"]23[/color][/b]) then { [] call fnc_toggleArrows; };"]; Change that to whatever you see fit. A list of the available keycodes can be found here.
  13. Spawning compositions is the nicer solution indeed, I'd prefer that too. The instructions on the Biki for cfgFunctions are pretty good. My example above is also working (I tested with exactly that)
  14. Sorry, I never worked with condition of presence, I just assumed. Tried it myself, looks like the init line call method is kicking in too late. Conditions of presence seem to be checked very early, even before init lines. The cfgFunctions method with preInit works though. :)
  15. You could place an object, like a game logic, and put this in its init line: call (compile preprocessFileLineNumbers "initPreprocessed.sqf"); Make sure you place this object before anything else in the editor, just to make sure it's called very early. Init lines, condition of presence etc. are executed in the order of mission.sqm. In other words, in the order of placement. Or, you could use cfgFunctions preInit, in your description.ext: class cfgFunctions { class YourFunctions { tag = "BL1P"; class Init { class init { file = "initPreprocessed.sqf"; preInit = 1; }; }; }; }; Both would archive what you're looking for. More about initialization order here
  16. Good point. Triggers set to ANY will be able to detect static objects as well, that's correct. I don't know how exactly triggers work under the hood, but they definitely are much faster than nearestObjects. They also run inside the non-scheduled environment, which makes them more performance friendly than running a loop inside a new thread. (With performance, in this this case, I mean clogging up the scripting engine) Although this kind of optimization is only a concern if you're working on a really large mission that runs A LOT of stuff. :) If you want to run a loop, you won't need a trigger at all. You just have to define the position. A self-made trigger so to speak :) _conditionMet = false; while {!_conditionMet} do { _units = _position nearEntities ["Man", 10]; _conditionMet = if (({isPlayer _x} count _units) > 0) then { true; } else { false; }; sleep 1; }; hint "a player is near the center!"; // Loop ended, same as trigger activated As you can see, I'm using nearEntities instead of nearestObejcts here. nearEntities is A LOT faster, but limited to certain objects (Men, Vehicles, and some other things). This method would be perfectly fine, even with a large radius (1000+ meters). Personally I'd go with the trigger, but performance-wise the difference should be very minor.
  17. You can disable JIP, in a way. Advisable? I don't know. That's up to you. I probably wouldn't bother doing so. Usually admins lock the server to archive this. You could simply add a time check to your init.sqf though: if (time > 60) then { endMission "End1"; }; This means, if mission has been running for more than 60 seconds, the mission will be ended for new players that join afterwards. The once-a-second-update is because the code F2k Sel gave you is not really a nice solution. There is no reason to run the attachTo command each second, attachTo attaches it, so you don't have to update it constantly, it will stay with the unit. It should be perfectly fluid following the object/player/vehicle. The loop is only needed to account for the vehicle change. The code I posted, has this extra line added, that waits for the vehicle to actually change, before attaching again: waitUntil {sleep 1; ((vehicle _player) != _vehicle)}; // Wait for vehicle change But no, theoretically the server could easily handle 14 loops with sleep 0.01. Depending on how much else is running, the server could handle 50 of that or more. :) However, I would let each client handle it's own marker: if (!isDedicated) then { _playerarrow = createVehicle ["Sign_Arrow_F", (getPosATL (vehicle player)), [], 0, "NONE"]; _playerarrow attachTo [player, [0,-0.5,3]]; while {true} do { _vehicle = (vehicle player); waitUntil {sleep 1; ((vehicle player) != _vehicle) || !(alive player)}; // Wait for vehicle change OR player not alive deTach _playerarrow; // Not sure if necessary if (!(alive player)) then { waitUntil {(alive player)}; }; // If player is dead, wait for respawn _playerarrow attachTo [(vehicle player), [0,-0.5,3]]; }; };
  18. You need to spawn one thread per player, or use a completely different method. If one of the 14 slots is empty (no player or ai) this will exit with an error (because pX doesn't exist at all). So it's probably better to use playableUnits + switchableUnits instead of direct references. Also, run this on the server only. Or use createVehicleLocal. Otherwise you will get 14 arrows per player. :D _player = (playableUnits + switchableUnits); { _x spawn { _player = _this; _playerarrow = "Sign_Arrow_F" createVehicle (getPosATL (vehicle _player)); _playerarrow attachTo [_player, [0,-0.5,3]]; while {alive _player} do { _vehicle = (vehicle _player); waitUntil {sleep 1; ((vehicle _player) != _vehicle)}; // Wait for vehicle change deTach _playerarrow; // Not sure if necessary _playerarrow attachTo [(vehicle _player), [0,-0.5,3]]; }; }; } forEach _player; This will not work with JIP and respawn however. If you use respawn or expect JIP, the code needs to be changed. Let me know.
  19. nearObjects returns "more" than nearestObjects. nearObjects includes things like insects and particles, but it's limited to a 50m radius (I think). Performance-wise they are both bad and shouldn't be used too often. A trigger will check a few times each second, it's too much for that. I'd set the trigger to ANY and use the following condition: (({isPlayer _x} count thisList) > 0)
  20. We tried a similar setpos workaround, but it wasnt working properly. setPos workaround is also problematic if your units start inside a vehicle (obviously). I now added a check right to BIS_fnc_moveToRespawnposition. Replace the function using cfgFunctions (no recompile allowance needed): class cfgFunctions { class A3 { class Respawn { class moveToRespawnPosition { file = "YOURDIR\fn_moveToRespawnPosition.sqf"; }; }; }; }; fn_moveToRespawnPosition.sqf /* Author: Karel Moricky Description: Move a unit to the respawn position. Parameter(s): 0: OBJECT 1: STRING - move to marker position OBJECT - move inside a vehicle (when seats are empty and not locked) or around it ARRAY - move to precise [X,Y,Z] position Returns: BOOL */ if (isNil "glt_respawn_fix_exit") exitWith { glt_respawn_fix_exit = true; }; _unit = [_this,0,player,[objnull]] call bis_fnc_param; _position = [_this,1,_unit,[[],"",objnull,grpnull]] call bis_fnc_param; _init = [_this,2,!isserver && time == 0,[true]] call bis_fnc_param; _fnc_setPos = { _posOrig = (_this select 0) call bis_fnc_position; _dummy = (typeof player) createvehiclelocal _posOrig; _pos = position _dummy; deletevehicle _dummy; _unit setpos _pos; if (count _this > 1) then { _unit setdir (_this select 1); } else { _unit setdir ([_pos,_posOrig] call bis_fnc_dirto); }; }; switch (typename _position) do { case (typename grpnull); case (typename objnull): { if (typename _position == typename grpnull) then {_position = leader _position;}; _obj = vehicle _position; _objPos = _obj call bis_fnc_position; if ( ( {_obj emptypositions _x > 0} count ["driver","commander","gunner","cargo"] > 0 || {{isnull (_obj turretunit _x)} count ([_obj,[]] call bis_fnc_getTurrets) > 0} ) && ( getnumber (configfile >> "cfgvehicles" >> typeof _obj >> "isUav") == 0 ) ) then { //--- Inside [_position,direction _obj] call _fnc_setPos; //--- Move near the vehicle in case moving in fails _unit moveinany _obj; } else { //--- Outside if ((_objPos select 2) > 20) then { //--- Parachute _para = createvehicle ["Steerable_Parachute_F",_objPos,[],0,"none"]; _para setpos _objPos; _para setdir direction _obj; _unit moveindriver _para; } else { _objPosATL = getposatl _obj; if ((_objPosATL select 2) > 1 && (_objPos select 2) < 1) then { //--- Building _unit setposatl _objPosATL; _unit setdir direction _obj; } else { //--- Ground [_obj,direction _obj] call _fnc_setPos; }; }; }; }; case (typename ""): { _direction = markerdir _position; if (_direction > 360) then {_direction = _direction / 360;}; [_position,_direction] call _fnc_setPos; }; case (typename []): { if ((_position select 2) > 20) then { //--- Parachute _para = createvehicle ["Steerable_Parachute_F",_position,[],0,"none"]; _para setpos _position; _unit moveindriver _para; } else { //--- Position _unit setposatl _position; }; }; }; true I only added this on top: if (isNil "glt_respawn_fix_exit") exitWith { glt_respawn_fix_exit = true; }; So the function will simply exit upon first call. This will however break start-position selection for JIP (if you're using that). We are using this as PBO (Addon), so it doesn't have to be added to all the missions. Download here if you're interested: glt_startpos_fix.rar
  21. Thanks for sharing these workarounds, looks like we're getting close to curing the player's Schizophrenia. :) I'll play around with these too and report back if I find any improvements. enableSentences false already made it a lot more bearable. BL1P, I would recommend using a server side addon for this stuff, so you don't have to add it to each mission, makes things easier. Example: // Compile and broadcast client_code = { if (isDedciated) exitWith {}; [] spawn { waitUntil {!(isNull player) && (time > 0)}; enableSentences false; showSubtitles false; player addMPEventHandler ["MPRespawn", { enableSentences false; showSubtitles false; }]; }; }; publicVariable "client_code"; // Execute everywhere incl. JIP [[], "client_code", nil, true, true] call BIS_fnc_MP; Just run this from a pbo on the server only. We've been using this method to apply such workarounds to all missions for quite some time now, works great.
  22. Stay away from fn_ambientAnim for multiplayer missions. There are certain BI Devs who COMPLETELY ignore the multiplayer side of things. Their functions are for SP only. This is one of them. Some of the BI functions have createVehicle without locality checks for example, it's crazy. I won't name names, but those devs have no idea about MP or locality AT ALL. It's a shame because he obviously put a lot of work into this function and it's a nice approach... absolutely useless in MP. You will have to do this on your own. Here's an example on how to loop basic animations for that. Let's call it ambientAnim.sqf: // Server only if (!isServer) exitWith {}; // Init switchMove function for animation broadcasting if (isNil "YOURTAG_fnc_switchMove") then { YOURTAG_fnc_switchMove = { (_this select 0) switchMove (_this select 1); }; publicVariable "YOURTAG_fnc_switchMove"; }; // Parameter _unit = _this select 0; // Unit _anim = _this select 1; // Animation name, string _loop = _this select 2; // Loop? _dir = if ((count _this) > 3) then { _this select 3; } else { (getDir _unit); }; // Dir is optional // Store _unit setVariable ["ambientAnim", _anim, false]; // Disable AI _unit disableAI "TARGET"; _unit disableAI "AUTOTARGET"; _unit disableAI "MOVE"; // Switch move [[_unit, _anim], "YOURTAG_fnc_switchMove", nil, true] call BIS_fnc_MP; // Wait a moment sleep 2; // Loop animation if (_loop) then { _animEh = _unit addEventHandler ["AnimDone", { [[(_this select 0), ((_this select 0) getvariable 'ambientAnim')], "YOURTAG_fnc_switchMove", nil, true] call BIS_fnc_MP; }]; }; // Dir correction _unit setDir _dir; _unit setPosATL (getPosATL _unit); // Snap out when hit _damage = damage _unit; waitUntil {sleep 0.2; ((damage _unit) != _damage)}; if (_loop) then { _unit removeEventHandler ["AnimDone", _animEh]; }; [[_unit, ""], "YOURTAG_fnc_switchMove", nil, true] call BIS_fnc_MP; _unit enableAI "TARGET"; _unit enableAI "AUTOTARGET"; _unit enableAI "MOVE"; You can call this from a unit's init line for example: nul = [this, "Acts_A_M04_briefing", true] execVM "ambientAnim.sqf"; // Normal animation, looped nul = [this, "Acts_A_M04_briefing", false] execVM "ambientAnim.sqf"; // Without loop (some anims are lopped autom.) nul = [this, "Acts_A_M04_briefing", true, 90] execVM "ambientAnim.sqf"; // With optional dir correction, it's needed for some animations, as you noticed Haven't tested this exact code, it's extracted from something I'm using though. It's not perfect, but it should give you a good basis to build upon.
  23. sxp2high

    Faction restrictions

    The uniform restriction is a very unfortunate limitation indeed. Still annoys me. The other way around would've been much better, something like uniform_limitations = true;, if not set, you can wear anything. In an old E3 video they even advertised changing uniform for disguise as a great new feature... Since when does the Geneva convention apply in video games? That's ridiculous. It's a work of fiction. That's like GTA removing the ability to steal cars, because it's against the law. If you mean "Ingame Geneva convention", they should just script it in. If you wear the wrong uniform, and get caught, you get court-martialed (mission ends). But I guess we have to deal with it. :(
  24. Tiny bit yea :) Let's call it measurement deviation.
  25. I actually ran all these test in a "real environment", a mission with a bit over 100 AIs fighting each other, vehicles driving around, a FOB with a lot of objects, civilians, and quite a few scripts running. 10.000 & 20.000 still have pretty good results, 387 objects were returned with "All".
×