Changeset 410

Show
Ignore:
Timestamp:
07/30/07 21:08:11 (1 year ago)
Author:
takkaria
Message:

Add the new object allocation system, as #310. Things will be a bit dodgy for a while. Note that this commit also adds in slightly different rarities for potions.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/externs.h

    r402 r410  
    166166extern store_type *store; 
    167167extern object_type *inventory; 
    168 extern s16b alloc_kind_size; 
    169 extern alloc_entry *alloc_kind_table; 
    170168extern s16b alloc_ego_size; 
    171169extern alloc_entry *alloc_ego_table; 
     
    432430extern object_type* get_first_object(int y, int x); 
    433431extern object_type* get_next_object(const object_type *o_ptr); 
    434 extern errr get_obj_num_prep(void); 
     432extern bool init_obj_alloc(void); 
     433extern void free_obj_alloc(void); 
    435434extern s16b get_obj_num(int level); 
    436435extern void object_known(object_type *o_ptr); 
  • trunk/src/init.h

    r103 r410  
    142142extern int error_line; 
    143143 
     144 
    144145#endif /* ALLOW_TEMPLATES */ 
    145146 
  • trunk/src/init1.c

    r346 r410  
    12831283                /* Save the values */ 
    12841284                k_ptr->level = level; 
    1285                 k_ptr->extra = extra; 
    12861285                k_ptr->weight = wgt; 
    12871286                k_ptr->cost = cost; 
     
    12911290        else if (buf[0] == 'A') 
    12921291        { 
    1293                 int i; 
    1294  
    1295                 /* XXX Simply read each number following a colon */ 
    1296                 for (i = 0, s = buf+1; s && (s[0] == ':') && s[1]; ++i) 
    1297                 { 
    1298                         /* Sanity check */ 
    1299                         if (i > 3) return (PARSE_ERROR_TOO_MANY_ALLOCATIONS); 
    1300  
    1301                         /* Default chance */ 
    1302                         k_ptr->chance[i] = 1; 
    1303  
    1304                         /* Store the attack damage index */ 
    1305                         k_ptr->locale[i] = atoi(s+1); 
    1306  
    1307                         /* Find the slash */ 
    1308                         t = strchr(s+1, '/'); 
    1309  
    1310                         /* Find the next colon */ 
    1311                         s = strchr(s+1, ':'); 
    1312  
    1313                         /* If the slash is "nearby", use it */ 
    1314                         if (t && (!s || t < s)) 
    1315                         { 
    1316                                 int chance = atoi(t+1); 
    1317                                 if (chance > 0) k_ptr->chance[i] = chance; 
    1318                         } 
    1319                 } 
     1292                int common, min, max; 
     1293 
     1294                /* Format is "A:<common>:<min> to <max>" */ 
     1295                if (3 != sscanf(buf+2, "%d:%d to %d", &common, &min, &max)) 
     1296                        return (PARSE_ERROR_GENERIC); 
     1297 
     1298 
     1299                /* Limit to size a byte */ 
     1300                if (common < 0 || common > 255) return (PARSE_ERROR_GENERIC); 
     1301                if (min < 0 || min > 255) return (PARSE_ERROR_GENERIC); 
     1302                if (max < 0 || max > 255) return (PARSE_ERROR_GENERIC); 
     1303 
     1304 
     1305                /* Set up data */ 
     1306                k_ptr->alloc_prob = common; 
     1307                k_ptr->alloc_min = min; 
     1308                k_ptr->alloc_max = max; 
    13201309        } 
    13211310 
  • trunk/src/init2.c

    r346 r410  
    12761276static errr init_alloc(void) 
    12771277{ 
    1278         int i, j; 
    1279  
    1280         object_kind *k_ptr; 
     1278        int i; 
    12811279 
    12821280        monster_race *r_ptr; 
     
    12911289 
    12921290 
    1293         /*** Analyze object allocation info ***/ 
    1294  
    1295         /* Clear the "aux" array */ 
    1296         (void)C_WIPE(aux, MAX_DEPTH, s16b); 
    1297  
    1298         /* Clear the "num" array */ 
    1299         (void)C_WIPE(num, MAX_DEPTH, s16b); 
    1300  
    1301         /* Size of "alloc_kind_table" */ 
    1302         alloc_kind_size = 0; 
    1303  
    1304         /* Scan the objects */ 
    1305         for (i = 1; i < z_info->k_max; i++) 
    1306         { 
    1307                 k_ptr = &k_info[i]; 
    1308  
    1309                 /* Scan allocation pairs */ 
    1310                 for (j = 0; j < 4; j++) 
    1311                 { 
    1312                         /* Count the "legal" entries */ 
    1313                         if (k_ptr->chance[j]) 
    1314                         { 
    1315                                 /* Count the entries */ 
    1316                                 alloc_kind_size++; 
    1317  
    1318                                 /* Group by level */ 
    1319                                 num[k_ptr->locale[j]]++; 
    1320                         } 
    1321                 } 
    1322         } 
    1323  
    1324         /* Collect the level indexes */ 
    1325         for (i = 1; i < MAX_DEPTH; i++) 
    1326         { 
    1327                 /* Group by level */ 
    1328                 num[i] += num[i-1]; 
    1329         } 
    1330  
    1331         /* Paranoia */ 
    1332         if (!num[0]) quit("No town objects!"); 
    1333  
    1334  
    13351291        /*** Initialize object allocation info ***/ 
    13361292 
    1337         /* Allocate the alloc_kind_table */ 
    1338         alloc_kind_table = C_ZNEW(alloc_kind_size, alloc_entry); 
    1339  
    1340         /* Get the table entry */ 
    1341         table = alloc_kind_table; 
    1342  
    1343         /* Scan the objects */ 
    1344         for (i = 1; i < z_info->k_max; i++) 
    1345         { 
    1346                 k_ptr = &k_info[i]; 
    1347  
    1348                 /* Scan allocation pairs */ 
    1349                 for (j = 0; j < 4; j++) 
    1350                 { 
    1351                         /* Count the "legal" entries */ 
    1352                         if (k_ptr->chance[j]) 
    1353                         { 
    1354                                 int p, x, y, z; 
    1355  
    1356                                 /* Extract the base level */ 
    1357                                 x = k_ptr->locale[j]; 
    1358  
    1359                                 /* Extract the base probability */ 
    1360                                 p = (100 / k_ptr->chance[j]); 
    1361  
    1362                                 /* Skip entries preceding our locale */ 
    1363                                 y = (x > 0) ? num[x-1] : 0; 
    1364  
    1365                                 /* Skip previous entries at this locale */ 
    1366                                 z = y + aux[x]; 
    1367  
    1368                                 /* Load the entry */ 
    1369                                 table[z].index = i; 
    1370                                 table[z].level = x; 
    1371                                 table[z].prob1 = p; 
    1372                                 table[z].prob2 = p; 
    1373                                 table[z].prob3 = p; 
    1374  
    1375                                 /* Another entry complete for this locale */ 
    1376                                 aux[x]++; 
    1377                         } 
    1378                 } 
    1379         } 
     1293        init_obj_alloc(); 
     1294 
    13801295 
    13811296 
     
    18261741 
    18271742        /* Free the allocation tables */ 
     1743        free_obj_alloc(); 
    18281744        FREE(alloc_ego_table); 
    18291745        FREE(alloc_race_table); 
    1830         FREE(alloc_kind_table); 
    18311746 
    18321747        if (store) 
  • trunk/src/object2.c

    r404 r410  
    573573 
    574574/* 
    575  * Get the next object in a stack or 
    576  * NULL if there isn't one. 
    577  */ 
    578 object_type* get_next_object(const object_type *o_ptr) 
     575 * Get the next object in a stack or NULL if there isn't one. 
     576 */ 
     577object_type *get_next_object(const object_type *o_ptr) 
    579578{ 
    580579        if (o_ptr->next_o_idx) return (&o_list[o_ptr->next_o_idx]); 
     
    585584 
    586585 
    587 /* 
    588  * Apply a "object restriction function" to the "object allocation table" 
    589  */ 
    590 errr get_obj_num_prep(void) 
    591 
    592         int i; 
    593  
    594         /* Get the entry */ 
    595         alloc_entry *table = alloc_kind_table; 
    596  
    597         /* Scan the allocation table */ 
    598         for (i = 0; i < alloc_kind_size; i++) 
    599         { 
    600                 /* Accept objects which pass the restriction, if any */ 
    601                 if (!get_obj_num_hook || (*get_obj_num_hook)(table[i].index)) 
    602                 { 
    603                         /* Accept this object */ 
    604                         table[i].prob2 = table[i].prob1; 
    605                 } 
    606  
    607                 /* Do not use this object */ 
    608                 else 
    609                 { 
    610                         /* Decline this object */ 
    611                         table[i].prob2 = 0; 
    612                 } 
    613         } 
    614  
    615         /* Success */ 
    616         return (0); 
    617 
    618  
    619  
    620  
    621 /* 
    622  * Choose an object kind that seems "appropriate" to the given level 
    623  * 
    624  * This function uses the "prob2" field of the "object allocation table", 
    625  * and various local information, to calculate the "prob3" field of the 
    626  * same table, which is then used to choose an "appropriate" object, in 
    627  * a relatively efficient manner. 
    628  * 
    629  * It is (slightly) more likely to acquire an object of the given level 
    630  * than one of a lower level.  This is done by choosing several objects 
    631  * appropriate to the given level and keeping the "hardest" one. 
    632  * 
    633  * Note that if no objects are "appropriate", then this function will 
    634  * fail, and return zero, but this should *almost* never happen. 
     586 
     587 
     588static u32b obj_total[MAX_DEPTH]; 
     589static byte *obj_alloc; 
     590 
     591/* Don't worry about probabilities for anything past dlev100 */ 
     592#define MAX_O_DEPTH             100 
     593 
     594/* 
     595 * Free object allocation info. 
     596 */ 
     597void free_obj_alloc(void) 
     598
     599        FREE(obj_alloc); 
     600
     601 
     602 
     603/* 
     604 * Using k_info[], init rarity data for the entire dungeon. 
     605 */ 
     606bool init_obj_alloc(void) 
     607
     608        int k_max = z_info->k_max; 
     609        int item, lev; 
     610 
     611 
     612        /* Free obj_allocs if allocated */ 
     613        FREE(obj_alloc); 
     614 
     615        /* Allocate and wipe */ 
     616        obj_alloc = C_ZNEW(MAX_O_DEPTH * k_max, byte); 
     617 
     618        /* Wipe the totals */ 
     619        C_WIPE(obj_total, MAX_O_DEPTH, u32b); 
     620 
     621 
     622        /* Init allocation data */ 
     623        for (item = 1; item < k_max; item++) 
     624        { 
     625                object_kind *k_ptr = &k_info[item]; 
     626 
     627                int min = k_ptr->alloc_min; 
     628                int max = k_ptr->alloc_max; 
     629 
     630                /* If an item doesn't have a rarity, move on */ 
     631                if (!k_ptr->alloc_prob) continue; 
     632 
     633                /* Go through all the dungeon levels */ 
     634                for (lev = 0; lev < MAX_O_DEPTH; lev++) 
     635                { 
     636                        int rarity = k_ptr->alloc_prob; 
     637 
     638                        /* Give out-of-depth items a tiny chance at being made */ 
     639                        if ((lev < min) || (lev > max)) rarity = 0; 
     640 
     641                        /* Save the probability */ 
     642                        obj_total[lev] += rarity; 
     643                        obj_alloc[(lev * k_max) + item] = rarity; 
     644                } 
     645        } 
     646 
     647        return TRUE; 
     648
     649 
     650 
     651 
     652 
     653/* 
     654 * Choose an object kind given a dungeon level to choose it for. 
    635655 */ 
    636656s16b get_obj_num(int level) 
    637657{ 
    638         int i, j, p; 
    639  
    640         int k_idx; 
    641  
    642         long value, total; 
    643  
    644         object_kind *k_ptr; 
    645  
    646         alloc_entry *table = alloc_kind_table; 
    647  
    648  
    649         /* Boost level */ 
    650         if (level > 0) 
    651         { 
    652                 /* Occasional "boost" */ 
    653                 if (rand_int(GREAT_OBJ) == 0) 
    654                 { 
    655                         /* What a bizarre calculation */ 
    656                         level = 1 + (level * MAX_DEPTH / randint(MAX_DEPTH)); 
    657                 } 
    658         } 
    659  
    660  
    661         /* Reset total */ 
    662         total = 0L; 
    663  
    664         /* Process probabilities */ 
    665         for (i = 0; i < alloc_kind_size; i++) 
    666         { 
    667                 /* Objects are sorted by depth */ 
    668                 if (table[i].level > level) break; 
    669  
    670                 /* Default */ 
    671                 table[i].prob3 = 0; 
    672  
    673                 /* Get the index */ 
    674                 k_idx = table[i].index; 
    675  
    676                 /* Get the actual kind */ 
    677                 k_ptr = &k_info[k_idx]; 
    678  
    679                 /* Hack -- prevent embedded chests */ 
    680                 if (opening_chest && (k_ptr->tval == TV_CHEST)) continue; 
    681  
    682                 /* Accept */ 
    683                 table[i].prob3 = table[i].prob2; 
    684  
    685                 /* Total */ 
    686                 total += table[i].prob3; 
    687         } 
    688  
    689         /* No legal objects */ 
    690         if (total <= 0) return (0); 
     658        /* This is the base index into obj_alloc for this dlev */ 
     659        size_t ind = level * z_info->k_max; 
     660 
     661        size_t item; 
     662 
     663        u32b value; 
     664 
     665 
     666        /* Paranoia */ 
     667        level = MIN(level, MAX_O_DEPTH); 
     668        level = MAX(level, 0); 
    691669 
    692670 
    693671        /* Pick an object */ 
    694         value = rand_int(total); 
    695  
    696         /* Find the object */ 
    697         for (i = 0; i < alloc_kind_size; i++) 
    698         { 
    699                 /* Found the entry */ 
    700                 if (value < table[i].prob3) break; 
     672        value = rand_int(obj_total[level]); 
     673        for (item = 1; item < z_info->k_max; item++) 
     674        { 
     675                /* Found it */ 
     676                if (value < obj_alloc[ind + item]) break; 
    701677 
    702678                /* Decrement */ 
    703                 value = value - table[i].prob3; 
    704         } 
    705  
    706  
    707         /* Power boost */ 
    708         p = rand_int(100); 
    709  
    710         /* Try for a "better" object once (50%) or twice (10%) */ 
    711         if (p < 60) 
    712         { 
    713                 /* Save old */ 
    714                 j = i; 
    715  
    716                 /* Pick a object */ 
    717                 value = rand_int(total); 
    718  
    719                 /* Find the monster */ 
    720                 for (i = 0; i < alloc_kind_size; i++) 
    721                 { 
    722                         /* Found the entry */ 
    723                         if (value < table[i].prob3) break; 
    724  
    725                         /* Decrement */ 
    726                         value = value - table[i].prob3; 
    727                 } 
    728  
    729                 /* Keep the "best" one */ 
    730                 if (table[i].level < table[j].level) i = j; 
    731         } 
    732  
    733         /* Try for a "better" object twice (10%) */ 
    734         if (p < 10) 
    735         { 
    736                 /* Save old */ 
    737                 j = i; 
    738  
    739                 /* Pick a object */ 
    740                 value = rand_int(total); 
    741  
    742                 /* Find the object */ 
    743                 for (i = 0; i < alloc_kind_size; i++) 
    744                 { 
    745                         /* Found the entry */ 
    746                         if (value < table[i].prob3) break; 
    747  
    748                         /* Decrement */ 
    749                         value = value - table[i].prob3; 
    750                 } 
    751  
    752                 /* Keep the "best" one */ 
    753                 if (table[i].level < table[j].level) i = j; 
    754         } 
    755  
    756  
    757         /* Result */ 
    758         return (table[i].index); 
     679                value -= obj_alloc[ind + item]; 
     680        } 
     681 
     682 
     683        /* Return the item index */ 
     684        return item; 
    759685} 
    760686 
     
    29642890                int k_idx; 
    29652891 
     2892#if 0 
    29662893                /* Good objects */ 
    29672894                if (good) 
     
    29732900                        get_obj_num_prep(); 
    29742901                } 
     2902#endif 
    29752903 
    29762904                /* Pick a random object */ 
    29772905                k_idx = get_obj_num(base); 
    29782906 
     2907#if 0 
    29792908                /* Good objects */ 
    29802909                if (good) 
     
    29862915                        get_obj_num_prep(); 
    29872916                } 
     2917#endif 
    29882918 
    29892919                /* Handle failure */ 
  • trunk/src/randart.c

    r399 r410  
    400400        target_level = k_ptr->level; 
    401401 
     402#if 0 
    402403        /* 
    403404         * Add base object kind's rarity to artifact rarity.  Later we will 
    404405         * subtract the new object kind's rarity. 
    405406         */ 
    406         a_ptr->rarity += k_ptr->chance[0]
    407  
     407        a_ptr->rarity += k_ptr->
     408#endif 
    408409        /* 
    409410         * Pick a category (tval) of weapon randomly.  Within each tval, roll 
     
    587588        kinds[a_idx] = k_idx; 
    588589 
     590#if 0 
    589591        /* 
    590592         * Subtract the new object kind's rarity (see above).  We can't 
     
    595597        else 
    596598                a_ptr->rarity -= k_ptr->chance[0]; 
     599#endif 
    597600 
    598601        a_ptr->tval = k_ptr->tval; 
  • trunk/src/types.h

    r404 r410  
    176176        u32b flags3;            /* Flags, set 3 */ 
    177177 
    178         byte locale[4];                /* Allocation level(s) */ 
    179         byte chance[4];                /* Allocation chance(s) */ 
    180  
     178        byte alloc_prob;       /* Allocation: commonness */ 
     179        byte alloc_min;                /* Highest normal dungeon level */ 
     180        byte alloc_max;         /* Lowest normal dungeon level */ 
    181181        byte level;                     /* Level */ 
    182         byte extra;                     /* Something */ 
    183182 
    184183 
     
    186185        char d_char;            /* Default object character */ 
    187186 
    188  
    189187        byte x_attr;            /* Desired object attribute */ 
    190188        char x_char;            /* Desired object character */ 
     189 
    191190 
    192191        u16b effect;            /* Effect this item produces */ 
  • trunk/src/variable.c

    r346 r410  
    482482 
    483483/* 
    484  * The size of "alloc_kind_table" (at most z_info->k_max * 4) 
    485  */ 
    486 s16b alloc_kind_size; 
    487  
    488 /* 
    489  * The array[alloc_kind_size] of entries in the "kind allocator table" 
    490  */ 
    491 alloc_entry *alloc_kind_table; 
    492  
    493  
    494 /* 
    495484 * The size of the "alloc_ego_table" 
    496485 */