Jump to content
Sign in to follow this  
456820

AI On Demmand?

Recommended Posts

Dont know if everyone remembers the COC AIOD scripts, which would basically delete the entire squad apart from the squad leader and when ever a player comes with in X Metres of that leader it will spawn the squad back up to full strength.

The script was very handy especially in reducing lag when a lot of units are on the map and we need as many lag reducing scripts in ArmA as possible biggrin_o.gif

So was just wondering if anyone was thinking of making something simillar or even converting the OFP version? Or am I blind and is their something like this already out for ArmA?

Thanks.

Share this post


Link to post
Share on other sites

afaik Mapfact is still working on a ArmA adaption of theyr excellent DAC which is pretty much what you're looking for.

Another system, which doesn't "delete" units when player out of range but creates groups when player approaches ist the ArmA Coop Essential Pack

Myke out

Share this post


Link to post
Share on other sites

Why don't you ask CoC themself?

Share this post


Link to post
Share on other sites

@Myke

Yeah the DAC does include basically what I want only problem is I already have the groups down.

I am using the Coop essential pack too (great work on that btw) however as I said above the squads are already placed down, plus spawning them seperate would ruin some of the mission due to different waypoints etc etc.

@Q

Normally I would however I have been brought up to think thats very cheeky, plus I do find it anoying when people PM me to ask me to do things.

Share this post


Link to post
Share on other sites

I'm tryin to write something but it may take a while...i'll provide it here and i'll also include it (when done) into the A-CEP aswell.

As i thought at the beginning, it doesn't seem to be very hard to script it...but i guess it will be hell to tweak it to lowest cpu consumption ;-)

Myke out

Share this post


Link to post
Share on other sites

it was way easier than i guessed....here it is:

http://www.armaholic.com/datas/users/372-cache_units.intro.zip

Little sample mission included, open in editor, click on preview and walk to the dude you're seeing....go forth and back to see the effect.

I build in that weapon loadout and remaining mags is also stored.

This thing is untested, need to verify what happens when leader gets killed, if the script correctly switches to new leader.

Any feedback welcome

Myke out

:EDIT:

tweaked it, should now recognize killed leaders and also adjusted deleting distance to +15 meters

Share this post


Link to post
Share on other sites

Thanks very much notworthy.gif

Will definately test it asap.

Edit - Forgot to ask, is this also MP compatible?

Share this post


Link to post
Share on other sites

Couldn't test it on server but as it is runnin server only it "should" work. But better you do some testing before.

As far as i can tell from my experience, i think it should run but ONLY with complete AI groups, not with playable units in it...but i guess this isn't really a downgrade ;-)

Myke out

:EDIT:

Just for completeness: this units caching script is now included into the ArmA Coop Essential Pack. Avialable here

Share this post


Link to post
Share on other sites

Ah good news...

I was looking for something similar. I'll try your version, as I tried to script it myself and it's not yet functional.

Malick

Share this post


Link to post
Share on other sites

Just had time to check the script and its very good, does just what I want really.

A small though though, some where in the script it should re-update the leader, call the group group1=group this

Somewhere should be

_leader = leader group1

for example, that should solve the leader not switching when the units are dead.

Does the script also store ammo levels? I see it adds the rigth weapon.

Also incase you wish to see how COC did it PM me and I shall send the scripts.

Great work so far. notworthy.gif

Share this post


Link to post
Share on other sites

It works nice. There are some bugs, though : if the player starts within the cache range, additional units are spawned...

Thank you Myke !

Malick

Share this post


Link to post
Share on other sites

Thx Malick, i'll check and fix this asap.

Ammo and Weapon loadout is stored with one downgrade: it doesn't check each mag how many rounds left but ithink thats not a big downgrade since AI will probably change mags only when empty.

About the group leader, in the above version it should definately check for actual group leader before caching units, please compare the code below with your version and note me if it's different:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

if (! isServer) exitwith {};

private ["_leader", "_unitarray", "_typearray"];

_leader = _this select 0;

_cache_side = _this select 1;

_cache_dist = _this select 2;

_grp = group _leader;

_unitarray = units group _leader;

_unitarray = _unitarray - [_leader];

_typearray = [];

{

_type = typeof _x;

_weap = weapons _x;

_mags = magazines _x;

_pos = _leader worldtomodel position _x;

_typearray = _typearray + [[_type, _weap, _mags, _pos]];

}

foreach _unitarray;

if (((_cache_side countside (position _leader nearobjects ["AllVehicles", _cache_dist])) == 0)) then

{

{

deletevehicle _x;

}

foreach _unitarray;

};

while {count _unitarray >= 1} do

{

waituntil {((_cache_side countside (position _leader nearobjects ["AllVehicles", _cache_dist])) != 0)};

{

_unit_init = _x select 0;

_unit_weap = _x select 1;

_unit_mags = _x select 2;

_unit_offset = _x select 3;

_unit_pos = _leader modeltoworld _unit_offset;

_new_unit = _unit_init createunit [_unit_pos, group _leader, "myunit = this"];

removeallweapons myunit;

{

myunit addmagazine _x;

}

foreach _unit_mags;

{

myunit addweapon _x;

}

foreach _unit_weap;

}

foreach _typearray;

waituntil {((_cache_side countside (position _leader nearobjects ["AllVehicles", (_cache_dist + 15)])) == 0)};

sleep 5;

_leader = leader _grp;

_unitarray = units group _leader;

_unitarray = _unitarray - [_leader];

_typearray = [];

{

_type = typeof _x;

_weap = weapons _x;

_mags = magazines _x;

_pos = _leader worldtomodel position _x;

_typearray = _typearray + [[_type, _weap, _mags, _pos]];

}

foreach _unitarray;

{

deletevehicle _x;

}

foreach _unitarray;

};

Myke out

Share this post


Link to post
Share on other sites

Hm... well I must have downloaded an older version since it seems to update with that script.

Also is it possible to get this to also work with vehicles such as tanks, it will spawn the crew for the tank just they wont get in it or anything.

Share this post


Link to post
Share on other sites

hmmm...i guess to make it work with any sort of vehicles will be a little trickier since the placement of the tanks has to check for buildings, bridges (imaging a tank created 10meters besides a bridge)....well...could happen to inf also....think i have to rework it. Anyhow, about buildings or walls i think for vehicles it isn't pretty usable.

Myke out

:EDIT:

Checked the script from the d/l link, it is definately the same version as posted above.

Share this post


Link to post
Share on other sites

Hi Myke,

I have tested your script for some time now. It works as intended and proves quite useful. Up till now, I have found the following issues :

- as already stated in a previous post, the script spawns additional units to a group when the player starts within cache range

- init eventhandlers are not passed to the cached units

Any idea how to fix this ? Thanks for your work.

Malick

Share this post


Link to post
Share on other sites

@Malick

Thx for your reply.

About the added units: will do an overwork, probably no big deal, just tweaking the routines.

About the EH...that might be a major problem. I have to look if i can read out the EH of a unit. If not, a workaround might be to make EH and the respective scripts as additional parameters. I'll see what i can do.

Myke out

Share this post


Link to post
Share on other sites

hey Myke smile_o.gif

great effort here mate!

You could check the ofp DAC version and see if Silola found a trick

to solve the EH problem.

best regards

Q

Share this post


Link to post
Share on other sites

@Q

Yep, will take a look at it.

Meanwhile i made some kind of workaround which seems IMHO the best solutions as it isn't limited to EH's but can also include any init-line statement desired.

THIS CODE IS UNTESTED ATM SO TEST IT BEFORE YOU USE IT IN ANY MISSION!

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

if (! isServer) exitwith {};

private ["_leader", "_unitarray", "_typearray", "_unit_init", "_init_line"];

_leader = _this select 0;

_cache_side = _this select 1;

_cache_dist = _this select 2;

if (count _this == 4) then

{

_unit_init = _this select 3;

_init_line = format ["myunit = this; %2", _unit_init];

};

else

{

_init_line = "myunit = this";

};

_grp = group _leader;

_unitarray = units group _leader;

_unitarray = _unitarray - [_leader];

_typearray = [];

while {count _unitarray >= 1} do

{

waituntil {((_cache_side countside (position _leader nearobjects ["AllVehicles", (_cache_dist + 15)])) == 0)};

sleep 5;

_leader = leader _grp;

_unitarray = units group _leader;

_unitarray = _unitarray - [_leader];

_typearray = [];

{

_type = typeof _x;

_weap = weapons _x;

_mags = magazines _x;

_pos = _leader worldtomodel position _x;

_typearray = _typearray + [[_type, _weap, _mags, _pos]];

deletevehicle _x;

}

foreach _unitarray;

waituntil {((_cache_side countside (position _leader nearobjects ["AllVehicles", _cache_dist])) != 0)};

{

_unit_init = _x select 0;

_unit_weap = _x select 1;

_unit_mags = _x select 2;

_unit_offset = _x select 3;

_unit_pos = _leader modeltoworld _unit_offset;

_new_unit = _unit_init createunit [_unit_pos, group _leader, _init_line];

removeallweapons myunit;

{

myunit addmagazine _x;

}

foreach _unit_mags;

{

myunit addweapon _x;

}

foreach _unit_weap;

}

foreach _typearray;

};

This should fixe the "add units" problem reported by Malick also.

Basic scriptcall stays "as is" but an optional parameter can be given.

Standard:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

nul = [this, SIDE, Distance] execVM "cache_units.sqf"

If you have some commands in the init line (except weapons scripts or commands as this is recognized automatically) like adding EH, you can provide these commands as you did in the init line...i.e addEventHandler:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

nul = [this, SIDE, Distance, "this addEventHandler ["killed", _this exec "player_killed.sqs"]"] execVM "cache_units.sqf"

See that initline parameter is passed as string, starting and ending with "

As in the initline, you can pass multiple commands separated with ;

NOTE THAT THIS WILL BE ADDED TO EVERY! UNIT CACHED!!!!

Please someone test it and report if it works as planed! Can't do it right now.

Myke out

Share this post


Link to post
Share on other sites

Nice job.

You might want to post ur code at pastebin.co.uk or pastebin.ca and link here for keeping it readable.

Also, the line with init line should be:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">nul = [this, SIDE, Distance, "this addEventHandler ['killed', _this exec 'player_killed.sqs']"];or:<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">nul = [this, SIDE, Distance, 'this addEventHandler ["killed", _this exec "player_killed.sqs"]'];

Also, the waitUntil loops loop in a very short time, you might want to add for instance sleep 2; in the waitUntils, eg:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">waituntil {sleep 2;((_cache_side countside (position _leader nearobjects ["AllVehicles", (_cache_dist + 15)])) == 0)};this might be important especially in cases where there are many many groups that use this script smile_o.gif

Also, you might want to add small sleeps to the forEach loops, of let's say sleep 0.2; , giving the engine some breathing space smile_o.gif

Also, seems small bug: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">};

else

{should be: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">}

else

{(I guess)

Also, you can use the _grp variable (as you define it) instead of multiple times grabbing the groups, e.g:<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_unitarray = units group _leader; to <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_unitarray = units _grp;

Also a tip on merging strings, you don't need to use format for this, e.g:<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_init_line = ("myunit = this; " + _unit_init);

Btw, Why do you use the myUnit globalVar? This can cause problems in case of multiple scripts running, it seems you can simply use the _new_unit var and drop the myUnit = this all together.

Share this post


Link to post
Share on other sites

@sickboy

Thx for the reply. As everyday i also lerned a few things today also.

Yep, the ' " issue, can cause headache biggrin_o.gif Thx for pointing to the problem, i always forget that.

Waituntil with sleep? Didn't knew that this works...as said above...learn something every day.

Yep, there's a ; too much, lack of testing possibilities atm, else i would have figured out.

Merging strings that way? Also didn't knew. But as the format thingy will probably not cause errors and also will probably not slowing down the script i'll keep that way up....let's say "to keep my style" biggrin_o.gif

Thx again to read through and point to some probs, i'm still learning sqf as i've just started a few weeks ago with.

Myke out

:EDIT:

About naming the units myunit...i've ancountered problems as in script sometimes the scriptinternal variable does not work (try it out with moveindriver a createunit created soldier). Can't remember for sure but i guess i encountered the same issue with addmagazine and addweapon. Have to re-test though as it might been another problem.

Share this post


Link to post
Share on other sites

Np. We're all learners smile_o.gif

Updated my post in the meantime again btw wink_o.gif

About the myUnit variable, and not working with local variable...

In this case it's probably because you don't have "_new_unit" in your private [] array. There's more missing from that array though, Personally I always insert all all local variables in there smile_o.gif

Share this post


Link to post
Share on other sites
Isn't having a nearObjects inside a waitUntil expensive?
Hence I suggested adding a sleep to it.

The problem is that afaik the only other method is using "distance" to every unit or player (on side X) on the map, or using triggers that move with the group leaders for every ai-on-demand group and checking for players/unitside inside the trigger. All not very "cheap", which is exactly the reason why I dropped the idea myself, as ArmA seems to handle large number of AI, especially when not in view, quite well, and the performance hit from all the scripts checking if they should rebuild the units would not make it any/much faster.

But this script looks promising.

Share this post


Link to post
Share on other sites
Quote[/b] ]

But this script looks promising.

sickboy, as i know some of your extraordinary works, hearing this from you make me feel honoured.

I guess this script will not make great sense on small to medium missions but on big ones it could help to keep servers FPS at a playable level.

Should be interesting to test what does consume more CPU power: 10 groups with 10 AI standard or the same groups with this script.

And about the private [] thing, i know about privating variables or as they're not transferred to a lower scope when not initialized or private'd. Even when it's not in there right now, i'm almost shure this was the first i tried when hunting this scriptbug.

Myke out

Share this post


Link to post
Share on other sites

Im looking forward to such test results aswell smile_o.gif

About the private variable thing, I can't think of any other reason why the weapon functions etc. would fail.

In case it still fails when privated, try adding a sleep of 0.1 behind the create to test, and otherwise adding a dummy initeventhandler to the unit, just to see if it has anything todo with having or not having an initeventhandler or any sorts of delay that might be connected to this.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×