Jump to content

xxanimusxx

Member
  • Content Count

    453
  • Joined

  • Last visited

  • Medals

  • Medals

Everything posted by xxanimusxx

  1. Well there is addMusicEventHandler which is quite handy, but unfortunately for you it's for ArmA3, so no luck for you :b There is no other way than this when using the Jukebox but to change the original files or make an Addon where some scripts are modified, which are either: /Expansion/Addons/modules_e.pbo//Jukebox/config.bin /Expansion/Addons/modules_e.pbo//Jukebox/data/scripts/jukebox.sqf. /Expansion/Addons/modules_e.pbo//Functions/misc/fn_music.sqf But you could fix yourself a custom Jukebox, just copy the code of fn_music.sqf and use some global variables to save the current track.
  2. Oh okay now it's more clear what you want to have :D Unfortunately say3D has local effects, so you have to broadcast it to everyone in order to achieve what say3D does - playing a sound in the perimeters of specified object. Just calling say3D will also output the audio, but just for you - everyone else, even one meter besides you, won't hear it. I'd suggest another approach for this, using public variables, which makes it a little more easy to broadcast those commands. // init.sqf if (!isDedicated) then { waitUntil {!isNull player}; outputCharge = { private ["_chargeSubj", "_group"]; _chargeSubj = (_this select 1); _group = group _chargeSubj; if (group player == _group) then { _chargeSubj groupChat "Charge!!!"; }; _chargeSubj say3D "SOUND"; }; "chargeSubject" addPublicVariableEventHandler outputCharge; if (side player == west) then { [] spawn { while {true} do { waitUntil {alive player}; waitUntil {inputAction "MoveFastForward" > 0}; chargeSubject = player; publicVariable "chargeSubject"; ["chargeSubject", player] call outputCharge; waitUntil {inputAction "MoveFastForward" == 0}; }; }; }; }; Okay the code above will do the following: If the player is on side west (BLUFOR): Wait until the player is alive (just a precaution) Wait until the player starts to sprint Broadcast the player to every client: If the broadcasted player is in the same group like the local players group, output "Charge!!!" play the defined sound in the perimeter of the broadcasted player [*]Because the publicVariableHandler won't get executed on the client which did the broadcast, manually call the handler [*]Finally, wait until the player isn't sprinting anymore and start from the top I dunno if this will work with respawning players, but in the worst case scenario you could wrap the code into a sqf-file and execVM it once in the init.sqf and after every respawn in the respawn event handler. Disclaimer: Didn't test this code in MP.
  3. Well that depends solely on your implementation :D Let us assume that fetch_data does nothing "heavy" and has no delays like sleeps in it, then spawning fetch_data will almost instantaneously spawn "yourOtherCode", so you won't have any major delays between that. But if you have a loop which shows constant informations with a fixed delay between every iteration, you're gonna be at a loss because "yourOtherCode" will be executed in the "same" time like your loop, so using the callback-method you have to think about other ways of synchronization (which is kind of difficult without mutexes/semaphores) because while you continue to execute the code in your loop, which finally shows something on the screen, "yourOtherCode" is executed without any means to control what is shown due to your loop. The usual approach is to define a global variable and use that in the output (concatenating), while feeding the global variable in your fetch_data-function. But this approach calls for pretty minor delays between each iteration because the spawned code eventually will take some milliseconds longer than the execution of the loop, so it's thinkable that your "special" output will lag behind for several milliseconds. So using a delay of five seconds between each loop iteration would cause some weird problems. But to sum this up: Are you really calling the code which has the loop in it? Isn't it eventually executed via execVM? Because if you call a script/function and have a loop in it, that loop will only last for a max. of 10000 iterations and skip the loop afterwards. Please be advised that you can't show the informations you want to output for a long time if that's the case. Imho you should execVM the script which holds the loop and use the waitUntil-method which is clearly more easy to implement and understand AND has the benefit that you don't have to synchronize anything :)
  4. Haha okay knowing PHP won't get you anywhere in ArmaScript ^^ The thing is - whener you spawn a function, you won't get a return value. Ever! Or let me rephrase that: You'll get a return value, like any other function does, but because your code after the spawn is being executed at the "same" time, you can't assign the return value to a (any) variable. If you even use one spawn in your code, you have to be clear on the consequences: if you want a return value from a spawned function, you have to wait after the spawn or put the code after the spawn into another function and call it in your spawned function. So you have to either forcibly wait until the spawned code has been executed and save the desired return values into a global variable so you can access them outta your function, or call another function after you're done. Because you didn't get my examples, I'll post some more detailed ones :) // Waiting for the spawned code fetch_data = { _key = _this; // do something here // put the results into the global array primary_data = [1, 2, 3, 4]; }; primary_data = []; _key = format["%1:",_myValueHere]; _fetch_data_handler = _key spawn fetch_data; waitUntil {scriptDone _fetch_data_handler}; _medical = primary_data select 1; _stats = primary_data select 2; _state = primary_data select 3; // using a callback fetch_data = { _callback = _this select 1; _key = _this select 0; // do something here _primary_data = [1, 2, 3, 4]; // at the end, spawn the callback _primary_data spawn _callback; }; yourOtherCode = { _primary_data = _this; _medical = _primary_data select 1; _stats = _primary_data select 2; _state = _primary_data select 3; }; _key = format["%1:",_myValueHere]; _fetch_data_handler = [_key, yourOtherCode] spawn fetch_data; I hope this explains it more to you. The callback-method looks rather discomfortable at the first sight, but when did right, it is more flexible. But if you don't want to change much in your code, you should opt for the waitUntil-method. However, if you're code to process the return-value of fetch_data is being called rather than spawned or execVM'ed, you can't use the waitUntil-method due to the same regulations about synchronous functions.
  5. Either you wait until the spawned code has been executed or you define a callback to be called after. // the waiting example myFunction = { _semaphore = _this select 0; // a regular string for naming the semaphore _otherparams = _this select 1; // .... // do something here // release the semaphore call compile format ["%1 = true;", _semaphore]; }; sem_mySem = false; ["sem_mySem", "param1", "param2"] spawn myFunction; waitUntil {sem_mySem}; // the callback example myFunction = { _callback = _this select 0; _otherparams = _this select 1; // .... // do something here // release the semaphore ["your", "desired", "parameters"] spawn _callback; }; _yourCallback = { _your = _this select 0; _desired = _this select 1; _paramseters= _this select 2; // do something here }; [_yourCallback, "param1", "param2"] spawn myFunction; Imho I'd take the callback one, I like that method a lot because you can define a common interface for the callback and stuff like that, which works better programatically.
  6. First of, _t = time; waitUntil {time - _t > 3}; is a really, really, fancy way to write sleep 3 . Furthermore the number and use of parameters in your RE-calls is off: [nil_or_caller, nil_or_target_object,"loc/per", script_to_execute, par0, par1...] call RE; So your RE-calls should look rather like this: [nil,player,"loc",rPLAYSOUND,"SOUNDFILE"] call RE; But this makes no sense at all, because if you use "player" as the target and "loc" as the condition, that translates to: playSound "SOUNDFILE"; //edit: okay, fair enough, your use of RE is by all means not wrong, but without more information about the whole scenario it seemed off to me :< And assigning something to "this"? Please, don't, just, don't xD To sum this up, what do you intend to do? Do you want the player who moves fast forward to hear a sound and read something on the screen or do you want every player to hear/see that? If its first, you don't have any MP problems because you can handle it like in SP, just use the "normal" functions like playSound and say. If you'd like to intend something else, please consider letting us in with some more information :)
  7. You just need to set the item you want to erase from the original array to any value which is unique in the array - as you already stated using the '3' would delete all threes, which is not desired. So you have to set that item to any other value, objNull being the favorite case. _array = [1, 2, 3, 4, 3, 5]; _array set [4, objNull]; _array = _array - [objNull]; You have to manually set the desired item to be erased, because there is no doable method to exclude duplicate items from erasion when using the binary operator '-'. Okay, here's a "short" lesson about datatypes used in ArmAScript: As this being a script language, there has to be some application interpreting and executing it - which is the game engine obviously. The game engine itself should be written in C(*), so you actually need to know the programming language to be able to really know which datatype takes how much memory. But these considerations are useless, because a scripting language is there to abstract from any requirements of knowledge concerning memory, datatype handling etc. Yes, arrays take up memory (afaik the most of memory any datatype takes in script languages), like every other variable you define in your script. Some may take memory just temporarily (local variables for instance), and others through the whole instance (I assume global variables). But arrays are handled a bit different due to memory considerations: an ArmAScript array can take any size (well I doubt that one but let's believe that for now) of items dynamically during run time, which means the interpreter (the game engine) has to offer some abstract data type which allows dynamic allocation of memory AND offer the possibility to take any datatype as array items the script language supports, which isn't an easy thing to achieve at all. So for every array you define in the script, there will be quite some memory allocation and managment going on in the background for that (I estimate multiple times of the memory a C(*)-array needs). So let's examine an example: _myArray1 = [1,2,3]; _myArray2 = _myArray1; _myArray3 = +(_myArray2); _myArray2 set [3, 4]; _myArray2 = [5, 6, 7]; _myArray3 set [0, 0]; So what do you think the three arrays contain after execution? Let's take a deeper look: _myArray1 is initialized with the numbers 1-3. _myArray2 is a "copy" of _myArray1, but the more exact term would be a reference (which is just 4/8-Bytes). So _myArray2 is pointing to _myArray1, which is wanted because in most cases you don't really want to copy the content of arrays. _myArray3 is actually a copy of _myArray2, which is a reference to _myArray1. This means _myArray3 is allocated the memory to hold the content of _myArray1. In the lower part of the code, we manipulate the arrays: The fourth item (zero based index!) of _myArray2 is set to 4, but because _myArray2 is just a reference, the actual change is being applied to _myArray1, resulting in [1,2,3,4]. After that _myArray2 is set with new items, and after this line _myArray2 ceases to be a reference and becomes an allocated array with the values [5,6,7]. In the end, the first item of _myArray3 is set to 0, resulting in [0, 2, 3] So what did we learn with this code? Every array you assign to another variable is just a reference unless you explicitly mark to copy the array (binary operator '+'). How can this be applied to your question however? Well you're assigning a local array to an object (in your case an existing group). Normally you'd expect it to actually copy the content over to the object, but this would mean more memory allocation and the base class of the object to hold different abstract data types to be assignable through the setVariable-command. Surprisingly enough even the setVariable command saves the reference of the array, not the contents of it. So you could manipulate the array you assigned to your group afterwards and the changes will be mirrored into the variable you get with getVariable. This holds true for singleplayer though, I can't say that for sure for multiplayer (you're broadcasting the variable after all), because the reference of your variable is only valid in your enviroment (your local game), but isn't for others. To answer your last question: you can't explicitly delete variables (and the allocated memory for it). But you can undefine a variable due to assingning nil to it. When the last reference to that variable ceases to exist, the allocated memory will be freed for further use. _myArray1 = [1,2,3]; _myArray2 = _myArray1; // _myArray2 is referencing _myArray1 _myArray1 = nil; // _myArray1 is undefined here, so _myArray2 points to nothing, but it still references _myArray1 _myArray2 = [4, 5, 6]; // _myArray2 is initialized with another array, so there are no references to _myArray1 anymore When and how the game engine decides to free allocated memory is not known to me and isn't even needed to be known by us scripters if the game engine handles everything right.
  8. I wouldn't use a trigger for this, but a script which is executed upon server initialization (init.sqf) if (isServer) then { [] spawn { waitUntil {(count allUnits) >= 300}; while {true} do { sleep 2000; waitUntil {({alive _x && !(fleeing _x)} count allUnits) < 300}; [xx] call DAC_Activate; }; }; }; If you don't want to have an infinite loop (you didn't meantion if your trigger is repeating or not) you can just erase the while-part.
  9. I hope you both have noticed that your if-clauses won't work as intended :S As I understood the query you want to either add a Binocular or NVgoggles AND either BAF_ied_v1 or BAF_ied_v2 to the same vehicle. But in case your random number happens to be 29, you'll add a Binocular AND NVgoggles AND one of the IED-types. How about this? waituntil {!isNil "bis_fnc_init"}; _car addWeaponCargoGlobal [(["Binocular", "NVgoggles"] call BIS_fnc_selectRandom), 1]; _car addWeaponCargoGlobal [(["BAF_ied_v1", "BAF_ied_v2"] call BIS_fnc_selectRandom), 1]; Don't forget to place the Functions-Module into your map for the above code to work.
  10. This script is intended to use for vehicles which have flipped over and therefore can't drive anymore. Executing the code-lines above will position the vehicle with it's Z-Coordinate pointing into the air, allowing the vehicle to drive again.
  11. Attach it to another object :D An object attacht to another doesn't seem to have a collision model anymore so it can also go through the ground and solid materials (which looks pretty weird actually). If this is not an option for you (which is quite understandable because the UAV would loose some abilities while attached to another object) you could write a custom damage-handler and nullify the damage done by the UAV by comparing the source of the damage with either the type of your UAV or the name of the UAV.
  12. It was pretty easy actually :D My first approach was waiting for an "-" and logging every consecutive key pressed after that until the enter-key was pressed to send the message away. But before scripting that I unpacked some pbo's from the dta/common folder of vanilla ArmA2OA in hope of finding some config entries with known names and behold, I did find some entries. All I had to do was finding out the IDD and IDC of the controls and voila, an infinite loop later we have all we need to grab the chat message :D The "hard" part was to write code handling the string comparison; not being able to use efficient c-code almost killed me... xD For all those to whom this information matters, here are the IDD's and IDC's of the controls: Chat-InputField: ParentClass-IDD: 24; InputField-IDC: 101; Channel-Label_ ParentClass-IDD: 63; TextField-IDC: 101;
  13. xxanimusxx

    AI Skil [Reference[l

    I think it was in the correct subforum as your question has nothing to do with scripting nor editing in a narrower sense :) Yet you posted here so I'm gonna answer with a command: setSkill. The BIKI-Page shows that there is a handful of skills an AI can have so I guess (and its really only a guess!) setting the Skill-Parameter of an AI in the mission Editor will count towards these individual skills. Furthermore the AI seem to be have more resistance against damage - shooting an AI in the chest in EASY will kill them but in higher difficulty levels you have to either shoot more rounds or hit the head directly. As I said, these are only guesses of mine and/or observations I did while editing missions.
  14. _locations = nearestLocations [getPos player,["nameCity","nameVillage"],12000]; _townNum = 1; _marker = ""; { _marker = createMarker [format ["town%1",_townNum], locationPosition _x]; _townNum = _townNum + 1; _marker setMarkerShape "Ellipse"; _marker setMarkerColor "ColorRed"; _marker setMarkerSize [300,300]; } forEach _locations; Or you could use: _locations = nearestLocations [getPos player,["nameCity","nameVillage"],12000]; _marker = ""; { _marker = createMarker [format ["town_%1", text _x], locationPosition _x]; _marker setMarkerShape "Ellipse"; _marker setMarkerColor "ColorRed"; _marker setMarkerSize [300,300]; } forEach _locations;
  15. You'd usually take a static string and add some random or incrementing numbers to it. _prefix = "locationMarker"; _counter = 1; { _marker = createMarker [format["%1_%2", _prefix, _counter], posOfLocation ]; _counter = _counter + 1; } forEach nearestLocations [...]; This example just shows how to create unique marker names - the rest of the code won't work as it should. You could also play with the attributes of the locations, like concatinating the name of the current location (_x) to the prefix.
  16. Afaik there is no way of (easily) finding out when and what the user is typing into the side chat - not with normal means that is. You could either search for the controls' IDs which are used to type in the text and hook you into the inputfield with an eventhandler or use a keydown-eventhandler on the whole screen and check the button sequences for an initial "-" (or to be on the safe road check with actionKeys for "Chat") and the following chars to match your string. You know what? The latter seems to be quite easy to do, I'll see if I can post an example :) /edit: I didn't forget you bud, just needed some time to script that out, but now its working: http://forums.bistudio.com/showthread.php?167485-Release-Chat-Events-Library
  17. Into the init.sqf: if (!isDedicated) then { nvGogglesActive = false; nvGoggleKeys = actionKeys "NightVision"; checkForNVGoggles = { _keyCode = _this; if (player hasWeapon "NVGoggles") then { if (_keyCode in nvGoggleKeys) then { _sound = if(nvGogglesActive) then {"NVG_Off"} else {"NVG_On"}; player setVehicleInit format["this say3D '%1';", _sound]; processInitCommands; clearVehicleInit player; nvGogglesActive = !nvGogglesActive; }; } else { nvGogglesActive = false; }; }; waitUntil {!isNull (findDisplay 46)}; (findDisplay 46) displayAddEventHandler ["keyPress", "(_this select 1) call checkForNVGoggles;"]; };
  18. Well that was to be expected, after all the information to use another command won't suffice here ... cutRsc is used to show HUD's or non-interactive GUIs. You have to define a RscTitles-class in your config and put your gui-classes in it. Btw, did you notice the attribute "movingEnable" in your ProgressBar-Class?
  19. unitSpawnGroup = group X1; X1 addEventHandler ["killed", { _this spawn { sleep 10; X2 = unitSpawnGroup createUnit ["US_Soldier_EP1", getMarkerPos "Xtest",[],0,"NONE"]; X2 setPos getMarkerPos "Xtest"; X2 setDir 80; [X2] joinSilent grpNull; }; }];
  20. Does your vehicle have cargo seats to begin with? Tanks usually just have turret/commander/driver seats, cargo seats are rare if your vehicle isn't normally used to transport units. If you want your team to start in the turret seats, you also have to consider the limitation of turret-seats in one vehicle and have to manually (you could also do it automatically but it's just too much work if its just for one specific vehicle) set the turret path in order to use moveInTurret
  21. The BIS-functions are part of the modules.pbo which is normally loaded into ArmA2 (OA) automatically on mission start when the Functions Module is placed into your mission. Unfortunately the documentation in the BIKI is limited to a few commands in the site you already meantioned. If you want to dig out more of the BIS-functions, either call BIS_fnc_help and use the GUI to traverse through the functions or (what I'm usually doing) get into Arma2/Common/modules.pbo/functions/ and brows through the sqf's or look into the cfgFunctions.hpp for a detailed listing.
  22. So you execute the first code if someone clicks "Set Location" and the second code when someone clicks "teleport"? Well if yes, that's your answer for your problem: remove the if-query around your first script and it will work. Use some hint's to output "finalLocation" if you're unsure if the variable is set.
  23. Well your problem is apparent: every client gets another location to spawn to - what you have to do hower is to assign one public variable with the location, not a global one :D //setPos.sqf by 2Lt M Henderson //For patrolling MkI //PNCOTC 6thAD //Gets a random position to spawn units in at a range of between 1500~2000 //Declare private variables private ["_radius","_location"]; if (isServer) then { //Set radius for spawn _radius = 0; while {_radius < 1500} do { _radius = random(2000); }; _location = getMarkerPos "Objective"; waituntil {!isnil "bis_fnc_init"}; finalLocation = [getMarkerPos "Objective", _radius, random 360] call BIS_fnc_relPos; publicVariable "finalLocation"; }; //setPos.sqf by 2Lt M Henderson //For patrolling MkI //PNCOTC 6thAD private ["_pole","_unit"]; _pole = _this select 0; _unit = _this select 1; //Spawn Player waitUntil {!isNil "finalLocation"}; _unit setPos finalLocation;
  24. I'm also in search of some method to get the squad-affiliation of a specific player but couldn't find anything like that. It is, however, pretty easy to get the player uid, well, using getPlayerUID. This ID is obviously unique and can be used to query specific data for the player. You didn't specify how you save these "badges" of yours, so I assume you have some database backing your mission? You just have to crosslink the playerUID with the database tables and can verify if the current player has the right amount of privileges to attain the special weapon sets. As for the weapons: Why do you put all the different weapons in the same box if your players shouldn't be able to pick them up in the first place? :D You could remove the weapons not suited for the particular player if you use local commands (not the ones with "Global" at the end) to fill the box so every player would see a different set of weapons in there. The other way round could be rather difficult - you have to keep track of the player and whenever he picks up some gear, you have to check for unwated items and remove them out of their equippment, so you'd need an infinite loop running on everyones client.
  25. The more pressing question here is: For what purpose do you need this? The AI don't rely on their "sight" (they are computer controlled, hence they can't really "see"), but on parameters like the position of ever object and the vectors projected upon these objects originating from the AI - it's all calculation 'n stuff (nevertheless, the unit being hidden could count towards the calculation as another parameter). What you can do, however, is selectively hide a unit, because hideObject's effect is local. It's a heck of work but you could locally hide the unit in question by executing the hideObject-command on every players client (!isServer), so the players wouldn't be able to see them, but the AI.
×