Jump to content

mrcurry

Member
  • Content Count

    641
  • Joined

  • Last visited

  • Medals

Everything posted by mrcurry

  1. I'll get right down to it. I have a list of classes retrieved from CfgVehicles and I need to filter out abstract (non-spawnable) classes so I can get to the good stuff. Anyone know of a way of doing this? Technically I could just try spawning the class and check if it returns anything but that just seems stupid and performance unfriendly. What I've got so far is a fairly standard fetching of classes. _cfgVehicles = configFile >> "CfgVehicles"; _lastIndex = count _cfgVehicles - 1; _return = []; for "_i" from 0 to _lastIndex do { _xConf = _cfgVehicles select _i; _xClass = configName _xConf; if(isClass _xConf) then { /*Some checks against other stuff*/ _return set [count _return, _xClass]; }; }; _return I've tried testing against the class' model ( getText (configFile >> "CfgVehicles" >> _x >> "model") ) and checking if it returns "" or "bmp". Weirdly enough it seems most abstract vehicle classes in cfgVehicles has the model "bmp" but not all of them, so this only gets me so far. What I would really want is a "isAbstract" command like so... _config = (configFile >> "CfgVehicles") select 0; if(!isAbstract _config) then { //Do stuff }; ...but any way of doing without resorting to spawning would be sweet. Thanks!
  2. mrcurry

    Arma 3: ambient modules?

    I'm guessing that goes for the other ambient modules as well? The ones I was interested in was civilians and vehicles.
  3. mrcurry

    Arma 3: ambient modules?

    I cannot find this in Beta 0.73.107682. Has it been removed during beta?
  4. Indoor building positions... It's one of those things that have been pretty elusive as far as arma scripting goes. I've been playing around with different ways of finding the positions but none of them have been satisfactory for a perfectionist like myself... Hence I create this topic, as a sort of brainstorm for possible solutions, from the simple to the outright insane. The essentials of the problem are: Imagine a function such as... fnc_findIndoorPositions = { //Stuff }; The parameter of the function would be a building of any kind. The return value must be an array of positions inside the building or an empty array. One could pre-define the positions through some "down and dirty" relative-position collecting. The plus side of this approach would be that you could define custom positions not defined in the buildings config. The drawback is the obvious that its massively time-consuming, especially for larger buildings which can have up to 50+ positions. It is also very inflexible. I've tried using commands like boundingBox to approximate the height of the building and have a rough "everything below rooftop level" selection, but buildings with several levels of roof kinda breaks it. Post your ideas or workarounds that you have, even a straight-up solutions are welcome. Oh, and leave the "it's impossible" attitude at the door. ;) Cheers /Curry
  5. Thanks for the feedback, I managed to get a function up an running with does the job decently. @cuel: Thanks for bringing my attention to the lineIntersectsWith command. It's an amazing addition to the SQF-library, so useful! Description: Using lineIntersectsWith you can trace the intersection between the model and lines going from positions outside the building you want to retrieve from. With that technique you filter the building positions into arch-types. With that in mind I put together the following function, it is a rewrite of my existing function for retrieving positions and allows for a more general use as well as sorting positions according to type. Input a building and it will get all positions in the building. Input a building in an array and it will retrieve all the building positions sorted into 3 nested arrays. In the first array you'll find all positions that are indoors. In the second are all positions that are on balconies and porches and the like. In the last array all outside positions are found, such as rooftops and ground-level positions. The function: /* ------------------------------------------------------------------------------------ Function: c_fnc_getBuildingPositions Can be used in 2 ways, simple and advanced Simple use: building call c_fnc_getBuildingPositions Parameter(s): building - Object Returns: All positions in a building Advanced use: [building (, offset)] call c_fnc_getBuildingPositions Parameter(s): [ building - Object , offset -(optional) Number - offset height which balcony-positions are measured against - default: 1.5 ] Returns: Array of 3 Arrays with positions sorted according to [ inside positions, balconies and porches, rooftops ] Beware, each nested array may or may not be empty, depending on the building. ------------------------------------------------------------------------------------ */ c_fnc_getBuildingPositions = { private ["_fnc_checkLOS", "_b", "_offset", "_aslPos", "_bBox", "_bBoxWidth", "_bBoxDepth", "_bBoxHeight", "_searchW", "_searchH", "_notVisable", "_visFromSide", "_visFromAbove", "_i", "_bP", "_xPos", "_visIndex", "_p"]; _fnc_checkLOS = { private ["_b", "_pos", "_width", "_height", "_facing", "_return", "_aPos", "_blockingObjects", "_nrVis", "_numChecks", "_dirDif", "_i", "_c", "_xDir", "_sidePos"]; _b = _this select 0; _pos = ATLtoASL (_this select 1); _width = _this select 2; _height = _this select 3; _facing = getDir _b; _return = 0; _aPos = [_pos select 0, _pos select 1, (_pos select 2) + _height]; _blockingObjects = lineIntersectsWith [_pos, _aPos]; if( !(_b in _blockingObjects) ) then { _return = 2; } else { _nrVis = 4; _numChecks = 12; _dirDif = 360/_numChecks; _i = 0; _c = 0; while {_i < _numChecks && _c < _nrVis} do { _xDir = _facing + _dirDif*_i; _sidePos = [(_pos select 0)+(_width*sin _xDir), (_pos select 1)+(_width*cos _xDir), _pos select 2]; _blockingObjects = lineIntersectsWith [_pos, _sidePos]; if (!(_b in _blockingObjects)) then { _c = _c + 1; } else { _c = 0; }; _i = _i + 1; }; if(_c == _nrVis) then { _return = 1; }; }; _return }; if(typeName _this == typeName []) then { _b = _this select 0; _offset = if(count _this > 1) then { _this select 1 } else { 1.5 }; _aslPos = getPosASL _b; _bBox = boundingBox _b; _bBoxWidth = ((_bBox select 1) select 0) - ((_bBox select 0) select 0); _bBoxDepth = ((_bBox select 1) select 1) - ((_bBox select 0) select 1); _bBoxHeight = ((_bBox select 1) select 2) - ((_bBox select 0) select 2); _searchW = if(_bBoxWidth > _bBoxDepth) then {_bBoxWidth} else {_bBoxDepth}; _searchH = _bBoxHeight; _notVisable = []; _visFromSide = []; _visFromAbove = []; _i = 0; _bP = _b buildingPos _i; while {{_x != 0} count _bP > 0} do { _xPos = [_bP select 0, _bP select 1, (_bP select 2) + _offset]; _visIndex = [_b, _xPos, _searchW, 50] call _fnc_checkLOS; switch (_visIndex) do { case 0: { _notVisable set [count _notVisable, _bP]; }; case 1: { _visFromSide set [count _visFromSide, _bP]; }; case 2: { _visFromAbove set [count _visFromAbove, _bP]; }; default { diag_log text format ["c_fnc_getBuildingPositions - Invalid _visIndex: %1", _visIndex]; }; }; _i = _i + 1; _bP = _b buildingPos _i; }; //Return [_notVisable, _visFromSide, _visFromAbove] } else { _b = _this; _p = []; _i = 0; _bP = _b buildingPos _i; while {{_x != 0} count _bP > 0} do { _p set [count _p, _bP]; _i = _i + 1; _bP = _b buildingPos _i; }; _p } }; The nested function _fnc_checkLOS can be, with some modification, used separately to check if any position is in a certain building. Known issues: Due to lineIntersectsWith not detecting some thin surfaces, window glass and some rooftops are not detected when checking Line Of Sight. In some cases this may cause odd sorting. Examples: Here is the test script I wrote for this function. It shows the usage of c_fnc_getBuildingPositions and will allow you to preview buildings in game. Usage: Place player in editor, add above code to init.sqf and add a repeatable radio-trigger Ingame you can trigger the test while looking at a building to show its positions and trigger it again to clean up. Red: Indoors Green: Balconies and porches Blue: Rooftops and outdoor positions
  6. Yes, I've seen his script and I feel that, while the work is solid and extensive, it is lacking in 1 important aspect. It has very little scale-ability. It is using the sort of "down and dirty" approach I was referring to in the OP. There is a lot work in making something like that (kudos to Jakerod) and adding more buildings to the script is... demanding to say the least even with his great comments, and it is exactly the kind of solution I am trying to avoid. Instead of cutting down the tree with an axe, I want to design a chainsaw. Hence I am looking for workarounds to the rather limited building configs and I'm trying to think outside the box (or the config if you will). Things like checking building height against an average floor height, dropping balls on top of the positions and checking if they get close enough for it to be a rooftop, etc. If you got any ideas, even somewhat crazy ones, do share! P.S. The ball option is currently not very good for run-time application. :rolleyes:
  7. I just thought I'd add that IMHO it is good practice to use private unless it is necessary to omit it. If you are writing functions for more complex systems or for other people having the habit of putting a private statement at the beginning of each scope can save you/them a lot of debugging headaches.
  8. Global Event Handler Allows a single machine to execute code on other machines running the script. Good for server wide broadcasts and such. This script consists of 2 parts. The event handling routine and the event broadcast routine. It's pretty straight forward. globalEventHandler.sqf Starts the event handler. Run through init.sqf or init fields. c_globalEventList = []; "c_globalEvent" addPublicVariableEventHandler { _eventArr = (_this select 1); "Network event recieved..." call c_fnc_debug_message; (_this select 0) call c_fnc_debug_global_var; c_globalEventList set [count c_globalEventList, + _eventArr]; c_globalEvent = nil; }; [] spawn { while {true} do { private ["_cEvent","_cArg","_cCode"]; if(count c_globalEventList > 0) then { _cEvent = c_globalEventList select 0; c_globalEventList set [0,-1]; c_globalEventList = c_globalEventList - [-1]; _cArg = _cEvent select 0; _cCode = _cEvent select 1; _cArg spawn _cCode; }; sleep 0.01; }; }; c_globalEvent_init = true; globalEvent.sqf The event function. Broadcasts the code to be executed to other machines. Parameters: 0 - arguments 1 - code private ["_t"]; _t = 0; waitUntil {(!isNil "c_globalEvent_init")}; c_globalEvent = + _this; publicVariable "c_globalEvent"; c_globalEvent = nil; doGlobalEvent.sqf Just like globalEvent.sqf this broadcasts the code to be executed but this also executes the code on the machine that calls it. Parameters: 0 - arguments - Anything. 1 - code - Code 2 - Condition for code to run locally - Boolean private ["_a","_c","_r"]; _a = _this select 0; _c = _this select 1; _r = if(count _this > 2) then {_this select 2} else {true}; waitUntil {(!isNil "c_globalEvent_init")}; if(if(typeName _r == "STRING") then {call compile (_r)} else {_r}) then {_a spawn _c}; [_a,_c] spawn c_fnc_globalEvent; @Demonized: Happens to everyone ;)
  9. Just thought I'd start this thread as I have a ton of small scripts lying about gathering dust. I will (eventually) come around posting 'em all on this thread. A lot of these scripts probably exist already. This is mostly an attempt to share what I've created over the course of many months as a source of inspiration for the many great minds on this forum. If you find something useful here then it's yours for the taking but remember: A real programmer doesn't claim someone else's work as his own. A real programmer give appropriate credit to the original author for the work on which his things are built. Enough ranting... Scripts: fnc_forEachTurret.sqf Function: Do code for each turret in a vehicle. Recursively searches the config of the vehicle to find all turrets and executes the given code when a turret is found. Parameters: 0 - Vehicle 1 - Code 3 arguments are passed to the code (accessible through _this): [vehicle, turret path, turret config entry] #define __opParam(index,def) if(count _this > index) then {_this select index} else {def} private ["_param1", "_code", "_path", "_conf", "_vec", "_turrets", "_hasTurrets", "_i", "_newPath"]; _param1 = _this select 0; _code = _this select 1; _path = __opParam(2,[]); _vec = __opParam(3,_param1); _conf = ""; switch(typeName _param1) do { case (typeName objNull): { _conf = (configFile >> "CfgVehicles" >> typeOf _param1); }; case (typeName (configFile >> "CfgVehicles")): { _conf = _param1; }; }; if(count _path > 0) then { [_vec, +_path, _conf] call _code; }; _turrets = _conf >> "Turrets"; _hasTurrets = false; if(!isNil "_turrets") then { if(count _turrets > 0) then { _hasTurrets = true; }; }; if(_hasTurrets) then { for "_i" from 0 to (count _turrets)-1 do { __DEBUG(_i); _x = _turrets select _i; _newPath = +_path; _newPath set [count _newPath, _i]; [_x,_code,_newPath,_vec] call compile preprocessFile "fnc_forEachTurret.sqf"; }; };
  10. I wrote this neat (and pretty straightforward tbh :P) function to simplify testing scripts written for triggers and inits, but it can just as well be used to add simple actions like "Show health". It work by taking the "arguments" parameter in addAction (see Biki) and interpret that as code to be run. The function handles both String and Code types, on invalid type default behavior is to print "Error in gen_action.sqf: Invalid type passed to function." in the arma2.rpt Parameters passed to the code being executed are: [target, caller, ActionID] Examples: Lets say we want to show how much health the player has with an action... instead of creating a .sqf file "getHealthAndShowItToPlayer.sqf" and calling addAction with that in the parameter we do this. //in soldiers init this addAction [ "Show health", "gen_action.sqf", {hint format ["Health: %1", damage player];} ]; (Note the {} around the code we want to execute) Of course we can add the other parameters like priority, showWindow, hideOnUse, etc... String instead of Code works too: this addAction [ "Express power", "gen_action.sqf", "player sideChat 'Muha, I got the powa!';", 10, false, true, "", "isServer" ]; We can also run caller/target dependent code using the parameters passed to the script: this addAction [ "Touch inappropriately", "gen_action.sqf", { (_this select 1) sideChat format [ "You have touched %1 inappropriately.", name (_this select 0) ]; } ]; Any questions, thoughts or bugs? Please feel free to post them. DISCLAIMER: This is not a recommended way to launch complicated scripts... if that is the case for you stick to a separate .sqf file. Download link
  11. mrcurry

    AC-130 Script for ARMA2 (0.3)

    The mod (script for that matter) is hardly, as you put it, "borderline useless" because of lagg. There is a warping effect on the plane yes and different solutions to this have been discussed, but the guns still shoot where they're supposed to. P.S. "the addon maker" would be LurchiDerLurch.
  12. mrcurry

    AC-130 Script for ARMA2 (0.3)

    You might just need another set of eyes to take a look at it m8. If you don't mind sharing PM me a link and I can take a look.
  13. mrcurry

    AC-130 Script for ARMA2 (0.3)

    You're not describing your problem well enough... - Is the problem that you can't get the FLIR working? - Is the problem that the infantry strobes or vehicle tracking isn't showing up? - Try to describe how to replicate the problem... - ... Get an english dictionary and get back when you can describe the problem properly. I might seem a bit harsh but we can't help you unless we know what you're talking about... which means you have to know what you're talking about.
  14. mrcurry

    AC-130 Script for ARMA2 (0.3)

    In LDL_init.sqf find this (should be around row 29) //ARMA2 Weapons LDL_ammo = ["G_30mm_HE","Sh_120_SABOT","Sh_120_HE"]; Element 1, 2 and 3 represent 25, 40 and 105 mm accordingly. Change the strings to the ammo classnames. A2 Ammo A2 CO Ammo
  15. mrcurry

    AC-130 Script for ARMA2 (0.3)

    Oops :D Noted and fixed previous post. I'd like to suggest/request adding an "official" function for rearming one and/or all of the weapons.
  16. mrcurry

    AC-130 Script for ARMA2 (0.3)

    I have been wanting to do just that for a while so I took some time to browe Lurchi's code and came up with this script. Not 100% tested but it seems to work most of the time and it should be multiplayer compatible. rearmAC130.sqf for v0.6 private ["_target", "_caller", "_id", "_object"]; _target = _this select 0; _caller = if(count _this > 1) then {_this select 1} else {nil}; _id = if(count _this > 2) then {_this select 2} else {nil}; _args = if(count _this > 3) then {_this select 3} else {nil}; _object = if(isNil "_caller") then {(vehicle _target)} else {(vehicle _caller)}; if(_object != _caller && !isNull _object) then { //--- Start --- _ac130_inUse = _object getVariable "LDL_planeInUse"; if(!isNil "_ac130_inUse") then { if(!_ac130_inUse) then { _object setVariable ["LDL_Ammo25", (LDL_options select 2), true]; _object setVariable ["LDL_Ammo40", (LDL_options select 3), true]; _object setVariable ["LDL_Ammo105",(LDL_options select 4), true]; } else { hint "Cannot rearm while plane is in use."; }; }; //--- End --- }; To run rearmAC130.sqf either use addAction or execVM addAction: //In init of plane or other objects this addAction ["Rearm AC130","rearmAC130.sqf"]; In-game simply look at the object the action is attached to while in the plane to rearm. execVM: [this] execVM "rearmAC130.sqf"; For advanced users: The actual rearming is done by the code in between //--- Start --- and //--- End --- in rearmAC130.sqf. rearmAC130.sqf for v0.7
  17. mrcurry

    Fallujah 1.1

    Then the bridges must be fixed, all I've got left to say is kudos for an awesome map.
  18. mrcurry

    Fallujah 1.1

    Very nice map, though I have a small request... If you release a new version please leave out the version number from the pbos. This is not entirely true since the new pbo's are named differently mission makers has to port each mission over. The game wont allow running 2 or more versions of the map so the normal "load, merge, save" approach doesn't work. Its a major headache to server admins and mission makers alike. So my request is: Don't rename pbo's for each new version, rather change the map name or something such. Edit: Are you aware that driving some vehicles over the bridges may cause it to bug out and the vehicles flips up in the air? (This was in version 1.0 but I didn't see anything about it in the new fixes).
  19. @HateDread Problem is that you save the ID to a variable local to the scope where the addAction is called, while the addAction spawns another script in which's scope the variable you try to utilize is not initialized or it contains complete jibberish, causing removeAction to fail in its task. One simple workaround would be to save the ID in the variable space of the object the action is attached to. _actionID = someGuy addAction [ "Do whatever", "gen_action.sqf", { _id = (_this select 0) getVariable "Strikeanswer_positive"; (_this select 0) removeAction _id; //Do whatever... } ]; _someGuy setVariable ["Strikeanswer_positive",_actionID]; A MP note on the command... AFAIK the action will only be added to the object on the machine that calls the addAction and the action ID may differ between seperate machines. In other words, addAction's effect is local to the calling machine. (Can someone please confirm/disconfirm? Without access to my computer I cannot atm) @Demonized I suspect using the extended syntax of the command (see addAction) is what you need. More specifically combining the condition parameter with distance and/or possibly cursorTarget
  20. mrcurry

    AC-130 Script for ARMA2 (0.3)

    First off, very nice script pack! It's just simply awesome having CAS in the form of a Spectre. Now I apologize upfront but I couldn't be arsed reading through all 30-40 pages of this thread so I'm simply reporting this, if it's a known issue just ignore my rant and please point me to a solution. I got the script variant (v 0.6) set up on a test mission with a plane sitting on the tarmac. I could jump in the plane just fine, go to co-pilot and access the camera. I had a go at blowing some nearby buildings up and I exit it aight... now here's the problem. I tried to access the camera again and it kept coming up with "AC-130 is unavailable", which it obviously wasn't. After a bit of testing I figured out the bandit(s) was a few settings in LDL_options... more specifically: "Disable Vehicle Detection" "Disable Infantry Strobes" "Disable Sounds" If 2 or more of these are set to true it causes the gun camera to only be accessible once before completely locking out any user from using the plane as intended. Now I took the liberty of having a quick look in the related scripts (I hope you don't mind) and found some interesting stuff: On a related note: "Show Infantry Strobes at startup" and "Show Vehicle Detection at startup" seems to override respective "Disable ..." option. Intended behavior? Edit: Noticed a .rpt message about some hex color codes. Problem lies in dialogParent.hpp.
  21. It's quite possible, though I'm not sure why you'd want to since the action code can do anything the trigger can. in condition field of trigger put a variable: bActiveTrigger The name of the variable doesn't matter as long as it's the same as below. Use addAction to set the variable to true. this addAction [ "Activate trigger", "gen_action.sqf", {bActiveTrigger = true; publicVariable "bActiveTrigger";} ]; Bam!
  22. Something along these lines should work (not tested it): Init this addAction ["Recruit","recruit_unit.sqf"]; this addAction ["Dismiss","dismiss_unit.sqf"]; recruit_unit.sqf Change the class names in _unitSet to the types you want to be able to spawn. _unitSet = ["ClassName","ClassName"]; _placementRadius = 5; _caller = _this select 1; _t = _unitSet select floor (random (count _unitSet)); _g = group _caller; _p = getPos _caller; _g createUnit [_t,_p,[],_placementRadius,"NONE"]; dismiss_units.sqf Select units to dismiss using f1-f10 and then use action. _caller = _this select 1; _u = groupSelectedUnits _caller; _u joinSilent grpNull; sleep 0.5; { deleteVehicle _x; } forEach _u;
  23. 1. Copy the gen_action.sqf to your mission folder. 2. Add the addAction command where you need it (see info and examples in OP). Note that the path to the file is relative to mission folder If I didn't get your question right simply ignore above.
  24. mrcurry

    CO16 Insurgency

    Very nice and polished mission, I think pretty much the entire community have fallen in love with it... and that's sayin a lot. Good job! The reason for my post is not only flattery though. From playing your mission I know you have managed to incorporate the First Aid modules (or atleast something similar) into your respawn system. I've been having trouble doing just that for a couple of weeks now and I wonder if you have any pointers to a fellow mission designer. Cheers Curry
  25. Very nice work lads! A few questions related to ACE. Is this mod ACE compatible and if no, is it at least planned to be? There are several features in ACE that could be combined with this to create some very interesting mission, like fast roping from a huey into really dense areas of the jungle. The traps were a very surprising touch and I gotta say I simply love em. Making my enemies fall into pits of sharpened stakes... awesome! Would be nice if a player could set them up during game. Some way to interact with them from a script (i.e. check if the trap is triggered etc) would make things a lot easier for mission makers.
×