Jump to content
Sign in to follow this  
MrSanchez

Need help with Arrays (Also random-related)

Recommended Posts

Hey guys, I'm trying to randomize some things, but want some things to have more priority...

Now without being vague, I'll give an example:

There are 5 random weapons e.g. pistol, submachinegun, assaultrifle, LMG, sniper

Only one of these 5 will spawn in ammo crate, but I want to create it so that the sniper has the slightest chance to spawn, e.g. 10%, and the pistol 50% for example..

How would I do this? I've already looked into the DayZ system, as it uses what I need, but it's a little bit confusing as its written in a config.cpp there.

While writing this thread, I might've found an alternative way to do this, but still confusing to me.

This is the chance that the item will spawn... How would I do something alike this but in SQF?

	itemType[] =	{
		{"ItemSodaMdew","magazine"},
		{"ItemWatch","generic"},
		{"ItemCompass","generic"},
		{"ItemMap","weapon"},
		{"Makarov","weapon"},
		{"Colt1911","weapon"},
		{"ItemFlashlight","generic"},
		{"ItemKnife","generic"},
		{"ItemMatchbox","generic"},
		{"","generic"},
		{"LeeEnfield","weapon"},
		{"revolver_EP1","weapon"},
		{"CZ_VestPouch_EP1","object"},
		{"DZ_CivilBackpack_EP1","object"},
		{"DZ_ALICE_Pack_EP1","object"},
		{"Winchester1866","weapon"},
		{"WeaponHolder_ItemTent","object"},
		{"","military"},
		{"","trash"},
		{"Crossbow","weapon"},
		{"Binocular","weapon"},
		{"PartWoodPile","magazine"},
		{"Skin_Camo1_DZ","magazine"},
		{"Skin_Sniper1_DZ","magazine"},
		{"WeaponHolder_MeleeCrowbar","object"},
		{"MR43","weapon"}
	};
	itemChance[] =	{
		0.01,
		0.15,
		0.05,
		0.03,
		0.13,
		0.05,
		0.03,
		0.08,
		0.06,
		2,
		0.06,
		0.04,
		0.01,
		0.03,
		0.03,
		0.01,
		0.01,
		0.03,
		0.5,
		0.01,
		0.06,
		0.06,
		0.01,
		0.01,
		0.08,
		0.03
	};

Now the alternative I found;

_weapons = [
{"M9SD",7},
{"Colt1911",3},
];

Is there some way of doing it maybe like this?

Basically, I just want to randomize it with priorities, now a very easy way to do this is to duplicate it in the array, so that there are two LMGs for example, but that takes alot of time and space.

So, how would I prioritize these weapons/loot

Share this post


Link to post
Share on other sites

Here's a script using that format based on a post by SaMatra :o to add random weapons and their mags. Should get you the basic idea of how to do it.

private ["_muzzles","_weapon","_pw","_item","_unit","_weaponChance","_itemChance","_clearAll","_weaponRoll","_itemRoll","_weaponList","_itemList","_defaultItems"];

// Called via: nul = [this] execVM "randomWeapons.sqf";
// Default 60% chance for weapons and items and clears previous items replacing them with Map, Watch, Compass and Radio.  Adjust _defaultItems to change that.
// Optional fields: nul = [this, 100, 30, false] execVM "randomWeapons.sqf" would always give a weapon, 30% give items and let you keep items you had before.
//
// Code based on ideas from SuMatra and Xeno.

// Declare unit and options from input arguments.
_unit = _this select 0;
_weaponChance = if (count _this > 1) then {_this select 1} else {60};
_itemChance = if (count _this > 2) then {_this select 2} else {60};
_clearAll = if (count _this > 3) then {_this select 3} else {true};

// Make the rolls to see if an item is given.
_weaponRoll = ceil (random 100);
_itemRoll = ceil (random 100);
//player sideChat format["Weapon: %1/%3 Item: %2/%4", _weaponRoll, _itemRoll, _weaponChance, _itemChance];

// List of weapons matched up with their ammo.
_weaponList = [
   ["UZI_EP1", "ACE_30Rnd_9x19_S_UZI"],
   ["ACE_USP", "ACE_12Rnd_45ACP_USP"],
   ["ACE_AK103", "ACE_30Rnd_762x39_AP_AK47"],
   ["ACE_G36K_iron", "30Rnd_556x45_G36"],
   ["ACE_G3A3", "ACE_20Rnd_762x51_B_G3"],
   ["ACE_gr1", "30Rnd_762x39_AK47"]
];

// List of possible reward items.
_itemList = ["ACE_Earplugs","Binocular_Vector","ACE_GlassesTactical"];

// List of default items to always have.
_defaultItems = ["ItemMap", "ItemWatch", "ItemCompass", "ItemRadio"];

// Clear weapons from the unit.
removeAllWeapons _unit;

// By default we'll remove all items as well to clear previous reward items and give back _defaultItems.
if (_clearAll) then { 
   removeAllItems _unit;
   {_unit addWeapon _x} forEach _defaultItems;
};

// If we're less than or equal to the weapon chance
if (_weaponRoll <= _weaponChance) then {
   // Pick a random weapon/mag pair from _weaponList.
   _weapon = _weaponList select floor(random(count _weaponList));

   //player groupChat format["Adding %1 and 2x %2", (_weapon select 0), (_weapon select 1)];

   // Add two of the selected mags
   for "_i" from 0 to 1 do {
       _unit addMagazine (_weapon select 1);
   };  

   // Add the selected weapon
   _unit addWeapon (_weapon select 0);

   // Ready weapon if it's got a GL muzzle.
   _pw = primaryWeapon _unit;
   if (_pw != "") then {
       _unit selectWeapon _pw;
       // Fix for weapons with grenade launcher
       _muzzles = getArray(configFile>>"cfgWeapons" >> _pw >> "muzzles");
       _unit selectWeapon (_muzzles select 0);
   } else {
       // If all they have is a pistol ready that.
       _unit selectWeapon (_weapon select 0);
   };
};

// If we're less than or equal to the item chance
if (_itemRoll <= _itemChance) then {
   // Pick a random item from the _itemList.
   _item = _itemList select floor(random(count _itemList));

   // player groupChat format["Adding %1", _item];

   // Give the item
   _unit addWeapon _item;
};

Edited by kylania

Share this post


Link to post
Share on other sites

I think every thread I ever made.. Kylania helped me out... but I'm still stuck on this one though.... This is close to what I want, the array and the usage of it sure will help me, but I still need some way of prioritizing individual weapons.. not by type like item or weapon or magazine... Like on DayZ an AS50 is alot more rare than a CZ 550...

Thanks in advance

Share this post


Link to post
Share on other sites

Haha, funny...

Nah, I was being vague because I didn't want anyone to get any ideas before I release my mission.. basically you're alone in Zargabad, all around you are hostile soldiers, you'll have to sneak around, gather guns in buildings, meet up with other survivors in the city (as its a co-op mission) and fight your way out of there waiting for backup... Something like that.. But I just want to prioritize my loot chances because I'm getting an AS50 or M107 rather often :P

So.. any clues on how to randomly pick something from an array, based on priority... e.g. "m1911" "as50" "m107", I want it so that the chances are random, yet there should be a way bigger chance for the m1911 than the as50 or m107..

That's a small example of my situation.

Share this post


Link to post
Share on other sites

//WeaponClass, MagazineClass, Chance
_weps = [
["SVD", "10Rnd_762x54_SVD", 1],
["M4A1", "30Rnd_556x45_Stanag", 9]
];

_keys = [];
for "_i" from 0 to (count _weps - 1) do {
for "_j" from 1 to (_weps select _i select 2) do {
	_keys = _keys + [_i];
};
};

_selected = _weps select (_keys select floor(random(count _keys)));

// Do something with _selected which will be one of the arrays inside _weps

Did not test it, but it should work and give you M4A1 in 90% cases and SVD in 10% cases.

Share this post


Link to post
Share on other sites

Hey SaMatra, thanks alot, with some basic testing and maths I noticed it works perfectly..

I will see if I am able to implement this in my loot system ;)

edit: second question, is there some way of using the modelname (.p3d) of a building and compare it

little example of what I'm trying to reach: if (modelbuilding _x == "a_office1.p3d") then {

edit2: Third question :P... I made a tent script which allows you to pitch up a tent, but is there some way of making it possible to store weapons in there without making addons? and if not, is there some empty ammocrate i can use instead?

Edited by PhonicStudios

Share this post


Link to post
Share on other sites

edit: second question, is there some way of using the modelname (.p3d) of a building and compare it

little example of what I'm trying to reach: if (modelbuilding _x == "a_office1.p3d") then {

Instead of model you can use typeOf _x which will return object classname which you can compare. Many and many objects don't have class names at all, for these cases there is a hard way: https://dev-heaven.net/issues/13031

edit2: Third question :P... I made a tent script which allows you to pitch up a tent, but is there some way of making it possible to store weapons in there without making addons? and if not, is there some empty ammocrate i can use instead?

No you can't without mod. Yes you can use some crate. Just spawn any you like and then clearWeaponCargoGlobal and clearMagazineCargoGlobal it. All crate class names are here: http://browser.six-projects.net/cfg_vehicles/tree?version=58 under "ReammoBox" class.

Share this post


Link to post
Share on other sites

Something like this using "weighted arrays".... the last number in the array is the actual weight.

_rifles = [
    ["MR43","2Rnd_shotgun_74Slug",0.01],
    ["Winchester1866","15Rnd_W1866_Slug",0.01],
    ["LeeEnfield","10x_303",0.01],
    ["huntingrifle","5x_22_LR_17_HMR",0.05],
    ["FN_FAL","20Rnd_762x51_FNFAL",0.10]
];

Then....

_weighted = [];

//rifles
for "_i" from 0 to (count _rifles)-1 do {
    _weight = (_rifles select _i) select 2;
    _weight = round(_weight * 100);
   for "_j" from 0 to (_weight - 1) do {
        _weighted set [count _weights,_j];
    };
    sleep 0.003;
};

_randrec = _weighted select floor (random (count _weighted));

_rifle = (_rifles select _randrec) select 0;
_ammo = (_rifles select _randrec) select 1;

This is similar to how it's done in DayZ...except there it's a function. Here it's part of the script. It creates huge arrays of numbers....but works.

I have a better way.... just haven't written the code as yet.

Edited by twirly

Share this post


Link to post
Share on other sites

Yeah.. forgot about clearmagazine/weapon thing :P..

The typeOf works perfectly, and the prioritizing too.

Thanks alot guys ;)

Share this post


Link to post
Share on other sites

@MrSanchez - I am currently working on the same concept of a random loot spawner with weights.  Any chance you can share your code that you used?  I am getting horribly stuck on this!   Much thanks in advance

Share this post


Link to post
Share on other sites
3 hours ago, TheGeneral2899 said:

@MrSanchez - I am currently working on the same concept of a random loot spawner with weights.  Any chance you can share your code that you used?  I am getting horribly stuck on this!   Much thanks in advance

 

Dayumn...5 years ago :O

I'm not sure if I still have the code, I'd have to search. It was working based on the weighting system Sa-matra posted above.

However, the last ArmA 3 update did introduce an interesting script command that may be perfect for what you want achieve: https://community.bistudio.com/wiki/selectRandomWeighted

 

Kind regards,

Sanchez

  • Like 1

Share this post


Link to post
Share on other sites

@MrSanchez - Hah I'm amazed you responded!  

 

I looked into that function but I don't understand if the weighted values are given directly the relevant.  For example: 

_values = [0,1,2,3,4,5,6,7,8,9];
_weights = [0.109,0.65,0.01,1.01,1.24,0,1.59,0.09,1.15,0.55];
_result = _values selectRandomWeighted _weights;

Is the first value in the values array (0), given the first value in the weights array (0.109)?

 

If not, how can I give a direct weight value to a specific value?

Share this post


Link to post
Share on other sites
2 hours ago, TheGeneral2899 said:

@MrSanchez - Hah I'm amazed you responded!  

 

I looked into that function but I don't understand if the weighted values are given directly the relevant.  For example: 


_values = [0,1,2,3,4,5,6,7,8,9];
_weights = [0.109,0.65,0.01,1.01,1.24,0,1.59,0.09,1.15,0.55];
_result = _values selectRandomWeighted _weights;

Is the first value in the values array (0), given the first value in the weights array (0.109)?

 

If not, how can I give a direct weight value to a specific value?

 

I've not used the command yet, but from the wiki, it seems like you're correct.

Let's say that the _values array is filled with classnames instead of numbers, and this script is used to pick what item will be randomly spawned on the ground, see the below code:

 

_values = ["arifle_Mk20C_F","arifle_Katiba_F","srifle_GM6_F"];
_weights = [6,6,1];
_result = _values selectRandomWeighted _weights;

In this example, the MK20 and Katiba have the same odds of being picked. But the GM6 is a lot less likely to be picked. If I recall maths correctly the odds of a GM6 is spawning is: 1 / (6+6+1)  = 0.077 = 7.7%

Whereas the mathematical odds of a MK20 or Katiba spawning is: 6 / (6+6+1) = 0,4615 = 46,15%

(Naturally, these chances would remain the same if the weights array would be e.g. [60,60,10] or [0.6,0.6,0.1] or [0.06,0.06,0.01])

 

Note you could also use the other syntax for this command if you'd wish. Hope this helps.

 

Kind regards,

Sanchez

Share this post


Link to post
Share on other sites

Amazing.  I believe I got it working and appreciate the insight.  Happy to bring back the thread after 5 years =)

 

Here is the code I used for anybody who needs in the future:

 

_rifles = [
    ["rhs_weap_m16a4","30Rnd_556x45_Stanag"], 0.18,
	["rhs_weap_m4", "30Rnd_556x45_Stanag"], 0.16,
	["rhsusf_weap_MP7A2_desert","rhs_ammo_46x30_FMJ"] ,0.27,
	["rhs_weap_m24sws","rhsusf_5Rnd_762x51_m62_Mag"], 0.05,
	["rhs_weap_sr25_d",	"rhsusf_20Rnd_762x51_m62_Mag"] ,0.07,
	["rhs_weap_ak74mr","rhs_30Rnd_762x39mm"], 0.17,
	["rhs_weap_pp2000",	"rhs_mag_9x19mm_7n21_20"], 0.28,
	["rhs_weap_svdp", "rhs_10Rnd_762x54mmR_7N1"], 0.08,
	["rhs_weap_aks74U",	"rhs_30Rnd_762x39mm"], 0.23,
	["rhs_weap_mk416d10", "30Rnd_556x45_Stanag"], 0.14,
	["rhs_weap_m590_5RD", "rhsusf_5Rnd_00Buck"], 0.18
];

_result = selectRandomWeighted _rifles; 
_equipmentCrate addMagazine (_result select 1); 
_equipmentCrate addWeapon (_result select 0);

 

  • Like 2

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  

×