Author Topic: Random Loot Generation based off substrings  (Read 372 times)

Legacy_SKIPPNUTTZ

  • Full Member
  • ***
  • Posts: 148
  • Karma: +0/-0
Random Loot Generation based off substrings
« on: November 23, 2011, 01:39:28 am »


               The following system is to be fired from the OnDeath event of boss creatures only.

What I have is about 1000+ blueprints of items that have become redundant due to better gear being available. These items used to be endgame options purchasable in our gameworld with a custom currency we call "Quest Points", which is basically like DKP. Below is kind of a template i set up in hopes of making a random loot generation based off substrings, to prevent us from having to make a case statement spanning over 1000 lines of code. The strings provided in GetStringRight are what all of these items use as prefixes, but all have random string lengths.  What I am hoping to accomplish here is getting some help making this process easy.

As an example:

I want case 1 to have a chance at spawning any item starting with "dys_qst_"
case 2 spawns any item starting with "elviquest"
etc, etc etc..

-----

While keeping all of the above in mind, I also need to make sure that any items ending in "_quiver" or having a base item type of ammunition, are never to be created.

I really appreciate any help our gameworld can get in reaching this goal. The thought of having to make a case statement with over 1000 resref's is sickening, and hours and hours of nonstop work. I would never even consider it.

I am somewhat of a novice scripter and just recently started working with substrings, and figured this could be achieved very easily in theory, if only I knew how to do it correctly. Obviously the code below does not work, or I would not be posting here. It's only giving the end substring as a result. By I tried adding this substring to the prefix and still nothing.

I put this script in the OnPhysicalAttacked event of a placeable that was plot, has an inventory, and is useable.
Loaded up the module to test this out and make sure its creating items, but nothing happens. Please help =D

-----------

void main()
{
    int nChance = d100();

    //5% chance of spawning a 6QP item on the corpse
    if(nChance <= 5)
    {
        string s6QP;
        int nRandom = 11;
        switch (nRandom)
        {
            case 01: s6QP = GetStringRight("dys_qst_",  8);   break; //Laura 6 QP Quest Items ("dys_qst_")

            case 02: s6QP = GetStringRight("elviquest", 7);   break; //Elvi 6 QP Quest Items ("elviquest")

            case 03: s6QP = GetStringRight("hpy_itmq",  8);   break; //Happy 6 QP Quest Items ("hpy_itmq")

            case 04: s6QP = GetStringRight("hpy_qitm",  8);   break; //Happy 6 QP Quest Items 2 ("hpy_qitm")

            case 05: s6QP = GetStringRight("quad",     12);   break; //Quad 6 QP Quest Items ("quad")

            case 06: s6QP = GetStringRight("slayer",   10);   break; //Slayer 6 QP Quest Items ("slayer")

            case 07: s6QP = GetStringRight("sly_",     12);   break; //Slayer 6 QP Quest Items 2 ("sly_")

            case 08: s6QP = GetStringRight("twn_q",    11);   break; //Twainer 6 QP Quest Items ("twn_q")

            case 09: s6QP = GetStringRight("wolfy_",   10);   break; //Wolfy 6 QP Quest Items ("wolfy_")

            case 10: s6QP = GetStringRight("wtr_q_",   10);   break; //Winter 6 QP Quest Items ("wtr_q_")

            case 11: s6QP = GetStringRight("wtr_qf_",   9);   break; //Winter 6 QP Quest Items 2 ("wtr_qf_")

        }

        CreateItemOnObject(s6QP, OBJECT_SELF, 1);
    }
}

               
               

               


                     Modifié par SKIPPNUTTZ, 23 novembre 2011 - 02:28 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Random Loot Generation based off substrings
« Reply #1 on: November 23, 2011, 03:32:48 am »


               We use substrings for spawning set loot - generally not more than 12-20 items, tops. For more, not only are you going to run into potential problems with overhead - string parsing is not particularly cheap, but managing 1k items in a single string is going to be a major headache.

There are two smart ways of doing this. One, is cases, which is what I did originally for our randomloot system, which handles around 1400 base items. If you go that route, they should be broken down into subfunctions, to handle various types, depending on the splits you want to make in your probability functions (rarity levels, item types, what have you).

Really, though, this kind of thing is what databases exist for. The problem is that in NWN, the default database is klunky enough to make using it for anything called this frequenty dubious, at best. If you have NWNX, though, its ability to interface with MySQL gives you databasing fast enough to handle this without breaking a sweat. We've begun converting our item tables to this, slowly, now, though it's been a backburner project for quite a while.

The reason that you want a database for this, in particular a NWNX-MySQL database, is that you can enter all kinds of related data in additional columns, like item type (if you want to make, for example, an armor rack), rarity (typical of most loot systems), area type found in (I would use a flagset for that, or unique incrementing numbers, based on ints set on area - our current system is a bit more general than I would do it if I were implementing it now). There are of course more types of information you could enter, but just item type and rarity would allow you to make armor racks (specific to a particular type, if you liked), which you could then cap based on area type. You could even assign weights to items (manually, or by code), and have MySQL select 1 or more for you. It is radically more powerful than any switch-based approach, due to its flexibility.

Of course, you can also keep it incredibly simple, if you like. If you want to plan long-term, I would advocate the database approach. I'm happy to post a full include you could use for the purpose, or just a sample database table, if you like.

Funky
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Random Loot Generation based off substrings
« Reply #2 on: November 23, 2011, 03:52:22 am »


               You could go the string parsing rout like you are discribing.  there are several way to do that.   But without fixed srting lengths, It just addes overhead to the string parser function.   You could just make all of your strings the same length by buffering unused characters with spaces.   still that can get a little messy and error prone if you miss just one space in buffering,   

  I would suggest that you forget about the string parsing method and instead go wit a 2da method.   You can build either a single 2da with all of the tables(column)   in it or a or a 2da per table.

your 2da would be a simple text file.   The text file on the first line has to be.  "2DA V2.0  " 
second line is blank. 
third line is column headings.
Every line after that is data.   

So you 2da could look something like this. 

2DA V2.0
     Table1                  Table2            Table3
0   dys_qst_1            elviquest1        hpy_itmq1
1   dys_qst_2            elviquest2        hpy_itmq3
3    ****                         elviquest3       ****
[/b]

 
 

Now if the name you saved the 2da as was tables.2da

you could get the information using: string sResRef = Get2DAString("tables", "Table2", 0);
would set sResRef equal to "elviquest1"  or what ever you had in that slot.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Random Loot Generation based off substrings
« Reply #3 on: November 23, 2011, 04:19:58 am »


               Actually, a 2da is another darn fine option these days, with the improved caching. Didn't even occur to me, and now that LF brings it up, that's what I'd recommend if you don't have NWNX. If you do, though, the database is a much better option.

Funky
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Random Loot Generation based off substrings
« Reply #4 on: November 23, 2011, 04:52:25 am »


               I agree with Funky,  If you have nwnx use the DB.  If not use the 2da.  The 1000 item packed string is just a bad Idea.