ATMA 5.04 and new DropCalc
#5
Not sure if this is of any interest. But When I have been calculating drop probabilities, I have been doing it the following way. It handle all type of pick combination of positive and negative values nested. It do NOT currently handle the very important "max 6 items" caps WHEN there is a negative pick value. For positive ones only, one can just scale all values down to 6 if it becomes larger than 6. I think one can add a parameter to count picks and simply move drops to a "drops above 6 items" category but I have not had time to implement it yet. Also if one want to add quality calcs, I have not done it since I was unsure how one would handle sub TCs having their own unique/set/rare/magic values. In addition, if different sub TCs have different such values, what happens?

Anyway, what I did was the following. FIrst, I load all relevant txt files (of course). I also have one big data matrix where for each TC, I will have a list of each item storing the probability values. I simply calculate it for all TCs and keep the values in memory. If memory is a problem, one can do it on a "desired TC" basis of course.

The algoritm is basically to go through the TC, entry by entry and keep track of the probabilities until one reach base items. This is done by a recursive function that takes a probability value as its entry (and some other stuff). When we start of, we enter with a prob=1.0 value. When then call the function for any sub TC, and pass along prob=prob*abs(picks)*(chance/totchance), that is, we calculate the probability of that specific being picked and multiply by the probability that we have so far (that is having taken the path so far to the sub TC we are at). We also multiply by the picks value since if it is larger than 1, we will have multiple entries form here on). When we reach an entry that is instead an item, we store that "prob" value on the item (adding up all such prob values reached). We also store a total probability value which would indicate number of items. If this total value is larger than 6, we can scale all values down so that it becomes 6 (for all poistive picks only). This works great from what I have seen with the exceptions I have yet to implement mentioned above.

I only have an older version of the code here (but it is quite similar to what I have now) so I will paste it here. Note that the code has a bunch of things that are remnants from older things I have been doing so might look strange at times. But it is more to get the general idea:




Code:
void markitem(int tcslot, int islot, double chance)
{
    if (islot!=-1)
    {
 tdrop[tcslot].fidrop[islot]+=chance;
 tdrop[tcslot].idrop[islot]+=1;
    }
    else
    {
 tdrop[tcslot].fnodrop+=chance;
 tdrop[tcslot].nodrop+=1;
    }
    tdrop[tcslot].fdrop+=chance;
    tdrop[tcslot].drop+=1;
} // markitem


Post comment:
Here I add the probability to the item (or to no drop for no item given). It seems I also keep track of how many times the item has been "added" to. Oh well, something I don't know if I use for anything, don't think so. At the end is the total probability which give the number of items you normally get from a monster.


void doonetc(int maintcslot, int tcslot, double chance)


Post comment:
the maintcslot is the entry TC I am calculating for, it is the TC I will store info in for each item. The tcslot is the current TC I am going through. chance is the current probability that we will come to that TC in a drop.


{
    // can be called recursively
    
    int        inbr;
    int        islot;
    int        nbrdrop,totdrop;
    struct tcdatatype    *tc;
    struct tcitemtype    *item;

    tc=&tcdata[tcslot];

Post comment:
This is the data structure where I keep treasureclass.exe info.


    // empty TC, nodrop=100%
    if(tc->nbr==0)
    {
 // set full chance to no drop
 markitem(maintcslot,-1,chance);
 return;
    }

Post comment:
tc->nbr would be the number of entries a TC has.



    // multiple items (can be merged with abs() )
    if(tc->picks>1)
    {
 // random picks
 chance*=(double)tc->picks;

    }
    if(tc->picks<-1)
    {
&nbsp;// negative picks
&nbsp;chance*=-(double)tc->picks;
    }
//    if(tc->picks>0)
//    {
// &nbsp;markmaxitems(maintcslot,tc->picks);
//    }

    // nodrop
    if((tc->nodrop!=0) && (tc->picks>0))
&nbsp;markitem(maintcslot,-1,chance*tc->nodrop/(double)tc->totprob);

    // Loop through all entries in TC
    nbrdrop=0;
    totdrop=0;
//    if(tc->picks<-1)
&nbsp;// negative picks
// &nbsp;totdrop=-tc->picks;


Post comment:
Below I loop through all the entries in the TC. Although my data handle it, this drop calculations does not handle unique and set items in the data fully. It do handle uniques though (so that the anihilus is handeled) by simply marking the base item of the unique as droping.


    for(inbr=0;inbr<tc->nbr;inbr++)
    {
&nbsp;if((tc->picks>0) || (nbrdrop<-(tc->picks)))
&nbsp;{
&nbsp;    item=&(tc->items[inbr]);
&nbsp;    nbrdrop+=item->prob;
&nbsp;    switch(item->type)
&nbsp;    {
&nbsp; &nbsp;case 0 :
&nbsp; &nbsp;    // an item
&nbsp; &nbsp;    markitem(maintcslot,item->slot,chance*item->prob/(double)tc->totprob);
&nbsp; &nbsp;    break;
&nbsp; &nbsp;case 1 :
&nbsp; &nbsp;    // another TC
&nbsp; &nbsp;    doonetc(maintcslot,item->slot,chance*item->prob/(double)tc->totprob);
&nbsp; &nbsp;    break;
&nbsp; &nbsp;case 2 :
&nbsp; &nbsp;    // unique item
&nbsp; &nbsp;    islot=getislot(udata[item->slot].abr);
&nbsp; &nbsp;    markitem(maintcslot,islot,chance*item->prob/(double)tc->totprob);
&nbsp; &nbsp;    break;
&nbsp; &nbsp;default :
&nbsp; &nbsp;    // something else
&nbsp; &nbsp;    break;
&nbsp;    }
&nbsp;}
    }

Post comments:

Below is were I scale for the 6 cap.


    // modify for more than 6 items (positive picks)
    if((tdrop[tcslot].fdrop>6.0) && (tc->picks>0))
    {
&nbsp;for(islot=0;islot<nbrislot;islot++)
&nbsp;{
&nbsp;    if(tdrop[tcslot].idrop[islot]>0)
&nbsp;    {
&nbsp; &nbsp;tdrop[tcslot].fidrop[islot]=6.0*tdrop[tcslot].fidrop[islot]/tdrop[tcslot].fdrop;
&nbsp;    }
&nbsp;}
&nbsp;tdrop[tcslot].fdrop=6.0;
    }
} // doonetc


void dotcprob(void)
{
    int &nbsp;tcslot;

    for(tcslot=0;tcslot<nbrtcslot;tcslot++)
    {
&nbsp;doonetc(tcslot, tcslot, 1.0);
    }
} // dotcprob

Here I simply loop all TCs and do the calcs for each one.


Have fun. Critisism or ideas are welcome.
There are three types of people in the world. Those who can count and those who can't.
Reply


Messages In This Thread
ATMA 5.04 and new DropCalc - by hakai_no_tenshi - 02-24-2004, 12:47 AM
ATMA 5.04 and new DropCalc - by hakai_no_tenshi - 02-24-2004, 07:31 AM
ATMA 5.04 and new DropCalc - by Samka - 02-24-2004, 10:28 AM
ATMA 5.04 and new DropCalc - by Ruvanal - 02-24-2004, 11:05 AM
ATMA 5.04 and new DropCalc - by Jarulf - 02-24-2004, 11:38 AM
ATMA 5.04 and new DropCalc - by Ruvanal - 02-24-2004, 09:00 PM
ATMA 5.04 and new DropCalc - by Jarulf - 02-24-2004, 10:02 PM
ATMA 5.04 and new DropCalc - by hakai_no_tenshi - 02-24-2004, 11:08 PM
ATMA 5.04 and new DropCalc - by Ruvanal - 02-25-2004, 02:22 AM
ATMA 5.04 and new DropCalc - by Jarulf - 02-25-2004, 06:16 AM
ATMA 5.04 and new DropCalc - by Samka - 02-25-2004, 08:01 AM
ATMA 5.04 and new DropCalc - by Jarulf - 02-25-2004, 08:03 AM
ATMA 5.04 and new DropCalc - by Samka - 02-25-2004, 09:59 AM
ATMA 5.04 and new DropCalc - by Jarulf - 02-25-2004, 10:22 AM
ATMA 5.04 and new DropCalc - by Jeger - 02-26-2004, 09:34 PM
ATMA 5.04 and new DropCalc - by Pansesus - 02-26-2004, 09:43 PM
ATMA 5.04 and new DropCalc - by hakai_no_tenshi - 02-27-2004, 12:44 AM
ATMA 5.04 and new DropCalc - by Jarulf - 02-27-2004, 01:02 PM
ATMA 5.04 and new DropCalc - by Thrugg - 02-27-2004, 09:31 PM
ATMA 5.04 and new DropCalc - by Jeger - 02-27-2004, 10:21 PM
ATMA 5.04 and new DropCalc - by Jarulf - 02-27-2004, 11:01 PM
ATMA 5.04 and new DropCalc - by Ruvanal - 02-27-2004, 11:15 PM
ATMA 5.04 and new DropCalc - by Jarulf - 02-29-2004, 12:52 PM
ATMA 5.04 and new DropCalc - by hakai_no_tenshi - 03-01-2004, 09:37 PM
ATMA 5.04 and new DropCalc - by Thrugg - 03-01-2004, 10:36 PM

Forum Jump:


Users browsing this thread: 2 Guest(s)