Jump to content

geqqo

Member
  • Content Count

    47
  • Joined

  • Last visited

  • Medals

Posts posted by geqqo


  1. ...

    sets it so if the AI are in the behavior defined they TP, not the other way around. E.G "COMBAT" = AI only TP if they are in COMBAT mode, not any other.

    Thus the != in the given expression. You may want to take a look at the following page, in case this is confusing - Operators on Biki.

    Appears that your code you gave was a bit off with the ( ) at the end

    The parenthesizing in the provided expression was to be used inside the if condition-delimiting parentheses (possibly along with other conditions) not in place of them, thus your initial failure. The parentheses in the provided sample aren't actually necessary (provided you encase the whole expression in parentheses), it's more of a style/readability matter (in this particular case).


  2. Sorry, that's what I get for being lazy and not testing my suggestions...

    That's what you must be looking for -

    (!isPlayer _x && behaviour _x != "COMBAT")||(_x==_ldr)

    Which effectively means "If unit is AI with non-combat behaviour OR unit is the triggering player..." (... then teleport the unit).

    This is still expecting the inline if solution (that determines the forEach input; which is either just the triggering player (if not squad leader) or all units in the group (both AI and players)).


  3. So what you want is -

    - squad leader can teleport with all units (players and AI) in the team

    - non-leader player members can teleport on their own (without taking the AI)

    ?

    That could be done as follows (if you want to write the position setting part only once; "..." stands for the regular position setting part in your code) -

    {...}forEach (if(_ldr == leader group _ldr)then{units group _ldr}else{[_ldr]});
    

    What this effectively does, is returning either the full group (if it's the leader) or only the player that triggered the action (if player is not the leader) for iteration by forEach. It's just using if inline to avoid typing the position setting code twice. This alone doesn't deal with behaviour limiting though.

    As for the behaviour checking. What I meant was, that you would need another forEach before the one you already have that would go through the units in the group (if the player's a leader in the first place) but instead of setting the position would check for the behaviour. To avoid the inline if altogether you could use another variable to store the unit array so the script would end up like -

    scopeName "actionscript";
    _unitstoteleport = [];
    
    //... your usual definitions here
    
    if(_ldr == leader group _ldr){
        {if(behaviour _x == "COMBAT")then{breakOut "actionscript"}} forEach units group _ldr;
        _unitstoteleport = units group _ldr;
    }else{
        _unitstoteleport = [_ldr];
    };
    
    {/* set position here */}forEach _unitstoteleport;

    This will cancel the teleport altogether if any AI unit is in "COMBAT" behaviour. To leave behind only the specific AI units with the "COMBAT" behaviour you could still instead use the other forEach code-sample (the one with the inline if) but add inside the forEach a check -

    {if(isPlayer _x||(!isPlayer _x && behaviour _x != "COMBAT"))then{/*set position here*/}}forEach ...


  4. Sorry, I must have been too ambiguous.

    The syntax for behaviour will allow to work as following -

    if(behaviour _yourunit=="COMBAT"){...

    You could use the check in either the same forEach to only teleport the specific AI units that aren't (or are) in "COMBAT" behaviour mode or you could use it in a preceding forEach (still for the same group, but to preliminarily check if any AI is (or is not) in "COMBAT" mode to judge whether the script should proceed to the teleporting forEach).

    The part in the forEach I meant as -

    {if(!isPlayer _x||_x == leader group _x)then{_x SetPos [(getMarkerPos _dest select 0)-10*sin(_dir),(getMarkerPos _dest select 1)-10*cos(_dir)]}} forEach units group _ldr;

    Also, as a little sidenote, _dir = random 359;, will in fact leave out a degree between 359-360, so 360 is probably what you mean to use there (random does not include the last integer itself but generates floating point (decimal) numbers up to that point).


  5. If the action wasn't shown only to the leader, then right after _ldr definition -

    if(_ldr!=leader group _ldr)exitWith{}

    Whether the player activating the script is his group's leader

    In the forEach -

    if(!isPlayer _x||(_x == leader group _x))then{...

    As for detection of combat mode for the AI; there isn't a specific check for "whether AI is in a firefight" (as far as I know), if that's what you meant, but you can take a look at AI Combat Modes on Biki


  6. As to why they would disappear on server restart, can't really tell as I would expect none of the previous info to carry over. Server restart shouldn't be any different from the first start, if it's a full mission restart from the lobby.

    Probably unrelated but if that's the full file in its literal form then the if(true) checks and using a _this variable wouldn't seem to be necessary.


  7. Replacing

    _this setDir _dir;

    with

    group _this setFormDir _dir;

    made the unit do the move correctly unless he was in a group. Otherwise I needed to add doStop _this; right after the setFormDir line. However, this will change the direction of the group, which may be unwanted; you could temporarily make the unit leave the group ([_this] joinSilent grpNull;) and later return him if it won't break anything in the particular situation. In my tests the unit did the move at an offset though, so I needed to adjust the dir accordingly (in my particular case +20 degrees when not in a group and -30 degrees with the doStop; regardless of initial group direction, possibly dependent on the used formation (he was doing the move towards a unit in the same group)).

    EDIT: Didn't notice your edit before posting.


  8. You can try getting the relative direction manually (with atan2), here's a simple test-case that works ok for me -

    Just place a player-unit and a second unit, name the second unit unit2. Put in the player unit's init:

    0 = this spawn {
        _pos1=position _this;
        _pos2=position unit2;
        _dir=((_pos2 select 0) - (_pos1 select 0)) atan2 ((_pos2 select 1) - (_pos1 select 1));
        _this setDir _dir;
        sleep 1;
        _this playMoveNow "ActsPercMrunSlowWrflDf_FlipFlopPara";
    };
    


  9. Well, yes, it will start acting as a global variable, once assigned. While naturally any keywords/commands shouldn't be used as variable names, I just expected for some reason for it to have special handling as a "data sink" (can't quite tell where I picked this up). Quite coincidentally, I had just recently started using nil to undefine variables and started getting "anomalous" results that I hadn't yet looked into very specifically, so when Burdy mentioned the warning, the problem became clear.


  10. My guess would be editing the z coord in the attachto?

    That's right (in my quick test case it looked quite ok), or you can go a step further and use worldToModel and modelToWorld

    _vehicle_23094 attachTo [_this,_this worldToModel (_vehicle_23094 modelToWorld [0,0,0])];//Not using the modelToWorld/worldToModel in either case caused some inconsistencies
    

    If I look really close, it actually still seems a little off ground (good enough though).

    EDIT: Viba's solution below is naturally much simpler :D


  11. According to createMarker biki page additional notes, you would need to define shape as well in addition to type for it to be shown. As for the trigger; it's working as written, if there's no enemies in the area and you're flying above 10 meters - there's "any" unit "present" and the number of units below 10 meters is not greater than 0, thus triggering the "false case" script that shows the red marker.


  12. You are referring to the VBS wiki, this functionality doesn't appear in createVehicle_array (the Arma 2 version).

    attachTo applied to your code (preserving usage of the two different variables that you are using for the vehicle) would look something like the following:

    _vehicle_23094 = objNull;
    _this = createVehicle ["HeliHEmpty",[4057.35, 11662.7, 0.000128174],[],0,"CAN_COLLIDE"];
    _this setDir 207.046;
    _vehicle_23094 = createVehicle ["Infostand_2_EP1", [4057.35, 11662.7, 0.000128174], [], 0, "CAN_COLLIDE"];
    _vehicle_23094 attachTo [_this,[0,0,0.9]];
    _this = _vehicle_23094;
    


  13. forcePos doesn't appear here, google doesn't give anything related either, what exactly are you referring to?

    You might be able to use attachTo with a "HeliHEmpty" (invisible object) vehicle to achieve what you want (I thought initially that it would've disabled clipping altogether but apparently not (quite; try for yourself)). Or set the position in OnEachFrame or a regular loop.


  14. Wow... must be the nil = 0 spawn { that I've been using in editor for testing (it doesn't like any value returned so I've been returning into nil but I guess it doesn't work like void in C or similar (got to fix some codes on my end now that I'm aware of this; never encountered this warning before, curiously, probably due to my singleplayer background)). Just replace it with 0 = 0 spawn{ .... Sorry about that :|


  15. player setpos [getspos this select 1, getpos this select 1, (getpos this select 2) ]

    Is it a typo here, or shouldn't the first one say 0, not 1 in there? Also in the first case it says getspos. An offset would be added by just doing -

    player setpos [(getpos this select 0) + 10, (getpos this select 1) + 10, getpos this select 2]
    

    For random placement around the point, you could use (just as an example, for practical uses, defining the global minRadius/maxRadius over at every init probably isn't the optimal solution) -

    minRadius = 5;
    maxRadius = 15;
    player setpos [
        (getpos this select 0) + ((minRadius + (maxRadius - minRadius))*(1 - random 2)),
        (getpos this select 1) + ((minRadius + (maxRadius - minRadius))*(1 - random 2))
    ];
    

    Is this for multiplayer or singleplayer and do you intend to spawn the groups mid-game or is an editor solution fine?

    As for BIS_fnc_findSafePos not working, you probably know this but just in case - you would need to include the Functions module first and then after waituntil {!isnil "bis_fnc_init"}; you can call the BIS functions like this - [[500,500,0],5,30,1,0,10,0] call BIS_fnc_findSafePos;.

    Here's an editor solution -

    Have one group leader's placement radius what you want it to be (or if you want to use several "random circle" areas, you can add markers and group the leader to those (you can do that, even though in group mode the markers are invisible), he'll be automatically spawned relative to a random one (along with his group), with the placement radius still in effect). Give the first group leader a name (for this example, I'm presuming leader1). Put this in the other group leader's (or any member's, but only to a single one) init -

    0 = [5,25,units group this,leader1] spawn {
          _minRadius = _this select 0;
          _maxRadius = _this select 1;
          _targetPos = getPos (_this select 2);
          {
                 _x setpos [
                        (_targetPos select 0) + ((_minRadius + (_maxRadius - _minRadius))*(1 - random 2)),
                        (_targetPos select 1) + ((_minRadius + (_maxRadius - _minRadius))*(1 - random 2))
                 ];
          }forEach (_this select 2);
    };
    

    Or you could predefine the latter part in init.sqf by using the same exact code as above, just replace the first line with these two lines

    moveUnitsToObject = {
        private["_minRadius","_maxRadius","_targetPos"];
    ...
    

    If using this, then in the second group leader's init (and any other group leader's init, if you want to move more groups) you would use -

    [5,25,units group this,leader1] call moveUnitsToObject;
    

    This will however make the troops move to their formation positions as they're all spawned randomly and are set to stick to formation by default (can be disabled in editor for each unit by setting the "Special" property to "None"). Alternatively you could define a custom function to place them correctly. I've displayed such a function in this post (as applyWedge that takes a group for argument); you'd just define that in init.sqf and call after moveUnitsToObject like this -

    group call applyWedge;
    


  16. The part in init.sqf is run for all (not enclosed in a isServer check or similar), right? Doubt, there's any problem with that, just to eliminate. Other than that I'm quite lost... as far as I can tell, there don't seem to be any reasons as to why this wouldn't work. So, perhaps you can include some debugging lines to visualize the state of things (especially with the other clients in mind (for whom it doesn't run)) and see where stuff goes off track (only for the single case of house just for testing; make backups of the originals, this functionality is just to trace the problem).

    Debug setup -

    init.sqf (will start to hintSilent the debug string every second and set it up to reset every time the EH triggers (so it can be repeatedly tested in a single game; the driver of h1 gets special handling, in that it resets when triggering the action); it'll also add an action that's avilable to all players that outputs the debugstring to the rpt for easier copying of the data (copyToClipboard is said to be unavailable on multiplayer)):

    //House of the Rising Sun Public Variable
    debugstring = "";
    playhouse = "";
    "playhouse" addPublicVariableEventHandler {//event handler ran on all machines to trigger when playXXXX is changed
        debugstring = format["pvEH _this:\n%1\n\npvEH playhouse:\n%2",_this,playhouse];
        [_this select 1] execVM "True\House.sqf";
    };
    0 = 0 spawn {
        player addAction ["debugstring to RPT","debug.sqf",nil,1.5,false,true,"","_this==_target"];
        while{true}do{hintSilent debugstring; sleep 1;};
    };
    

    debug.sqf:

    diag_log text debugstring;
    

    Variables/playhouse.sqf:

    if(player == driver h1)then{debugstring = ""};
    debugstring = (debugstring + format["\n\nactionscript _this/3:\n%1\n\nactionscript playhouse 1:\n%2",_this select 3,playhouse]);
    playhouse =  _this select 3;
    debugstring = (debugstring + format["\n\nactionscript playhouse 2:\n%1",playhouse]);
    publicVariable "playhouse"; // new playXXXX variable value sent to other non-local machines, to trigger eventhandler
    [playhouse] execVM "True\House.sqf"; //for client (activator) to play script.
    debugstring = (debugstring + "\n\nactionscript OK");
    

    True/House.sqf:

    debugstring = (debugstring + format["\n\nsay3dscript-exvm _this:\n%1\n\nsay3dscript-exvm getV _this/0:\n%2\n\nsay3dscript-exvm h1:\n%3",_this,missionNamespace getVariable (_this select 0),if(isNil "h1")then{"nil"}else{h1}]);
    (missionNamespace getVariable (_this select 0)) say3d "house";
    debugstring = (debugstring + "\n\nsay3dscript (execVM) say3d OK");
    hint "Radiowave 'House of the Rising Sun' taken";
    sleep 248;
    hint "Radiowave 'House of the Rising Sun' open";
    playhouse = "";
    

    I expect the testing to be done on the heli that's h1. If you can't make anything critical out of it, a screenshot of or text copy of the contents of the hint a few seconds after the publicVariable has commenced (if it does at all) on the client for whom the sound isn't working, might help.

×