Jump to content
Sign in to follow this  
Publik

Standalone Code - Inefficient Weighted Loot Selection

Recommended Posts

Will standalone use the same kind of code as the mod? I assume the scripts will be rather similar... If so, if you take a look at the weighted loot spawning code it's really inefficient. Like, trying to clean a fish with a brick inefficient. If it's using the same code I have a cleaner version I wrote for the now-defunct Freeside Coalition Edition we were working on at the end of the summer. It's cleaner, can be scaled much farther than the previous one, and is bounds more accurate.

For a list of items I with weights W, the current algorithm needs to allocate a new array of size Σ(Ii * Round(Wi * 100)) where W is a double or float between 0.0 - 1.0, to then traverse and populate every time it wants to pick a new loot item. The version I've got doesn't need to allocate an array at all. It needs an int, long, or float and the original array of weights and that's it. The old version can only support weights of 0.00 - 1.00 (2 decimal places, or only 100 possible weights). The version I've got doesn't care what the weights are. They could be doubles or ints or longs and nothing would change.

Could I send this in somewhere or what? Even if standalone isn't using the same language, if it's using the same method it'll still be clunky.

  • Like 1

Share this post


Link to post
Share on other sites

Possibly contact one of the mods or the community coders or rocket himself and see if they require it

Share this post


Link to post
Share on other sites

Not sure if the mods would be very helpful or if I can actually get in contact with Rocket in any way from here. Who are the community coders?

Share this post


Link to post
Share on other sites

Not sure if the mods would be very helpful or if I can actually get in contact with Rocket in any way from here. Who are the community coders?

Just writen an Mail to Matt Lightfoot hes the contact to Rocket and the Community Dev. Team

http://dayzmod.com/f...matt-lightfoot/

Edit:

some community coders are

R4Z0R49

http://dayzmod.com/f.../11955-r4z0r49/

Ander

http://dayzmod.com/f...ser/8255-ander/

Edit 2:

and here´s the full list

Community Dev Project Sponsor

* Rocket

Community Dev Project Manager

* R4Z0R49

Communtiy Devs

* Alby

* Ander

* Ayan4m1

* f0rt (ashfor03)

* R4Z0R49

* Rajko

* Stapo

* Venthos

* Pwnoz0r

Edited by Paddy0610
  • Like 1

Share this post


Link to post
Share on other sites

Right-o, thanks

Going to dump my stuff here as a reference:

compiles.sqf:


// Original method:
BIS_fnc_selectRandom = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\fn_selectRandom.sqf"; //Checks which actions for nearby casualty

// Add:
PUB_fnc_selectRandom = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\fn_selectRandomlyWithWeights.sqf"; //PUBLIK'S VERSION

In building_spawnLoot.sqf and wherever weighted arrays are used:


// Replace:
_weights = [_itemType,_itemChance] call fnc_buildWeightedArray;
_index = _weights call BIS_fnc_selectRandom;

// With:
_index = _itemChance call PUB_fnc_selectRandom;

fn_selectRandomlyWithWeights.sqf


/*
Author: Jeff Rosenberg

Takes: [_weights]
_weights: The array of number weights. Items array doesn't matter, as long as the arrays match indexes.

Returns: The index of an item selected from a weighted list of passed length
*/
private["_sum", "_current", "_index", "_target"];

// Get the sum of the weights
_sum = 0;
for "_number" from 0 to ((count _this) - 1) do
{
_sum = _sum + (_this select _number);
};

_current = 0;
_index = -1;
_target = random _sum; // Pick a number between 0 and _sum

// Select the item
while { _current < _target; } do
{
_index = _index + 1; // Increment the index
_current = _current + (_this select _index); // Add another weight. If we've passed _target, we've selected the index _target resides in
};
_index

Note, I don't actually know C. I know C++ and C#; blame a modern education. These may be stupidly dirty, but the logic is sound.

Basically, draw a line from x=0 to x=sum of weights. Starting at x=0, put a mark every _weights[n] spaces. For _weights of [1, 2, 3, 5] you'd have a line like this:


-0-|--1--|---2----|--------3-------
0--1--2--3--4--5--6--7--8--9--10-11
|--|--|--|--|--|

[0-1] is index 0

[1-3] is index 1

[3-6] is index 2

[6-11] is index 3

Pick a number between 0 and sum (let's say 5). Now go over the line.

The segment containing 5 is the one belonging to the index I want to select.

The selection sits after 2 and before 3, so I select index 2 as it holds all random selections between 3 and 6.

Essentially, this is the same as doing the current ticketing method, except I don't care if a weight section is from 0.00001 to 0.1 or 100 to 1000. In the end it works out the same, except I'm not allocating an array and filling it with _items every time. The code needs an array.sum method if one already exists and the while() loop, while functional, could probably be done better.

Edit: And good God, what's with the

 tags??? The green! :emptycan:
Edited by Publik

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  

×