Angband.oook.cz
Angband.oook.cz
AboutVariantsLadderForumCompetitionComicScreenshotsFunniesLinks

Go Back   Angband Forums > Angband > Development

Reply
 
Thread Tools Display Modes
Old July 8, 2010, 20:51   #11
Tiburon Silverflame
Swordsman
 
Join Date: Feb 2010
Posts: 405
Tiburon Silverflame is on a distinguished road
Given that it's C code, HIGHLY possible.

I hate C as an application language...
Tiburon Silverflame is offline   Reply With Quote
Old July 8, 2010, 22:44   #12
PowerDiver
Prophet
 
Join Date: Mar 2008
Posts: 2,712
PowerDiver is on a distinguished road
Quote:
Originally Posted by Tiburon Silverflame View Post
Given that it's C code, HIGHLY possible.

I hate C as an application language...
C is not the problem. The function is easy to read. The question is whether init_obj_alloc() is the function that actually sets up object allocation. It would not be surprising if someone did something somewhere else that overrides it or modifies it somehow.
PowerDiver is offline   Reply With Quote
Old July 9, 2010, 09:02   #13
ewert
Knight
 
Join Date: Jul 2009
Posts: 525
ewert is on a distinguished road
Code:
43	/*
44	 * Using k_info[], init rarity data for the entire dungeon.
45	 */
46	bool init_obj_alloc(void)
47	{
48	        int k_max = z_info->k_max;
49	        int item, lev;
50	
51	
52	        /* Free obj_allocs if allocated */
53	        FREE(obj_alloc);
54	
55	        /* Allocate and wipe */
56	        obj_alloc = C_ZNEW((MAX_O_DEPTH + 1) * k_max, byte);
57	        obj_alloc_great = C_ZNEW((MAX_O_DEPTH + 1) * k_max, byte);
58	
59	        /* Wipe the totals */
60	        C_WIPE(obj_total, MAX_O_DEPTH + 1, u32b);
61	        C_WIPE(obj_total_great, MAX_O_DEPTH + 1, u32b);
62	
63	
64	        /* Init allocation data */
65	        for (item = 1; item < k_max; item++)
66	        {
67	                const object_kind *k_ptr = &k_info[item];
68	
69	                int min = k_ptr->alloc_min;
70	                int max = k_ptr->alloc_max;
71	
72	                /* If an item doesn't have a rarity, move on */
73	                if (!k_ptr->alloc_prob) continue;
74	
75	                /* Go through all the dungeon levels */
76	                for (lev = 0; lev <= MAX_O_DEPTH; lev++)
77	                {
78	                        int rarity = k_ptr->alloc_prob;
79	
80	                        /* Save the probability in the standard table */
81	                        if ((lev < min) || (lev > max)) rarity = 0;
82	                        obj_total[lev] += rarity;
83	                        obj_alloc[(lev * k_max) + item] = rarity;
84	
85	                        /* Save the probability in the "great" table if relevant */
86	                        if (!kind_is_good(k_ptr)) rarity = 0;
87	                        obj_total_great[lev] += rarity;
88	                        obj_alloc_great[(lev * k_max) + item] = rarity;
89	                }
90	        }
91	
92	        return TRUE;
93	}
94	
95	
96	
97	
98	/*
99	 * Choose an object kind given a dungeon level to choose it for.
100	 */
101	s16b get_obj_num(int level, bool good)
102	{
103	        /* This is the base index into obj_alloc for this dlev */
104	        size_t ind, item;
105	        u32b value;
106	
107	        /* Occasional level boost */
108	        if ((level > 0) && one_in_(GREAT_OBJ))
109	        {
110	                /* What a bizarre calculation */
111	                level = 1 + (level * MAX_O_DEPTH / randint1(MAX_O_DEPTH));
112	        }
113	
114	        /* Paranoia */
115	        level = MIN(level, MAX_O_DEPTH);
116	        level = MAX(level, 0);
117	
118	        /* Pick an object */
119	        ind = level * z_info->k_max;
120	
121	        if (!good)
122	        {
123	                value = randint0(obj_total[level]);
124	                for (item = 1; item < z_info->k_max; item++)
125	                {
126	                        /* Found it */
127	                        if (value < obj_alloc[ind + item]) break;
128	
129	                        /* Decrement */
130	                        value -= obj_alloc[ind + item];
131	                }
132	        }
133	        else
134	        {
135	                value = randint0(obj_total_great[level]);
136	                for (item = 1; item < z_info->k_max; item++)
137	                {
138	                        /* Found it */
139	                        if (value < obj_alloc_great[ind + item]) break;
140	
141	                        /* Decrement */
142	                        value -= obj_alloc_great[ind + item];
143	                }
144	        }
145	
146	
147	        /* Return the item index */
148	        return item;
149	}
Okay is the lines of 72 to 88 the problem? Where is alloc_prob defined? I don't know much c, was more of a basic/pascal/java guy myself when a kid. =P But these are the relevant parts of the generation code as far as I can tell. As I said I don't quite follow what it says, but does it create the allocation info for each level separately?

From what I can tell, if I could code properly in c I would guess it is not a big change, but seems to need both parsing changes in alloc_prob and changes here to use multiple values if available ...
ewert is offline   Reply With Quote
Old July 9, 2010, 17:45   #14
Tiburon Silverflame
Swordsman
 
Join Date: Feb 2010
Posts: 405
Tiburon Silverflame is on a distinguished road
Why does the item loop go from 1 to < k_max? This actually says you can never allocate more than (k_max - 1) items. No biggie, just curious...

The major problem is lines 69 and 70.

Look at the loop structure. It's per item, first. Get the item, then get the *single fixed* min/max level numbers and rarity; I assume these are from the A: line, ewert. These have to be recoded to themselves be level-dependent. In pseudocode:

for level = 0 to MaxDepth
for objectIndex = 1 to LastObject
obj = ObjectTable[objectIndex]
rarity = obj.getRarity(level)
if rarity > 0
...add object to lists as necessary

Yeah, I think in depth first, more than in items...but it wouldn't matter.

Then you need a getRarity for the objects, which should just be keeping all the A: lines separate. Start from the first, return the first rarity where the input (level) matches the bounds on the A: line. If none do, return 0. So we make alloc_min and alloc_max arrays.


64 /* Init allocation data */
65 for (item = 1; item < k_max; item++)
66 {
67 const object_kind *k_ptr = &k_info[item];
68
69 int min = k_ptr->alloc_min;
70 int max = k_ptr->alloc_max;
71
72 /* If an item doesn't have a rarity, move on */
73 if (!k_ptr->alloc_prob) continue;
74
75 /* Go through all the dungeon levels */
76 for (lev = 0; lev <= MAX_O_DEPTH; lev++)
77 {
int rarity = 0;
int numAllocs = k_ptr->allocs_count; /* new field, computed during parsing */
for (alloc = 1; alloc <=numAllocs; alloc++) {
int min = k_ptr->alloc_min[alloc];
int max = k_ptr->alloc_max[alloc];
if (lev >= min && levl <= max)
{
78 rarity = k_ptr->alloc_prob[alloc];
break;
}
79
80 /* Save the probability in the standard table */
81 if ((lev < min) || (lev > max)) rarity = 0;
82 obj_total[lev] += rarity;
83 obj_alloc[(lev * k_max) + item] = rarity;
84
85 /* Save the probability in the "great" table if relevant */
86 if (!kind_is_good(k_ptr)) rarity = 0;
87 obj_total_great[lev] += rarity;
88 obj_alloc_great[(lev * k_max) + item] = rarity;
89 }
90 }

I believe that should do it...barring indexing issues, I don't recall if C arrays start at 0 or 1.

This would take a tiny bit more time, but given that it's a one-shot process done during creation, that's not a factor.
Tiburon Silverflame is offline   Reply With Quote
Old July 9, 2010, 18:38   #15
PowerDiver
Prophet
 
Join Date: Mar 2008
Posts: 2,712
PowerDiver is on a distinguished road
The parser has a comment that only one A: is allowed. Unfortunately whoever wrote it was too lazy to put in a check to produce an error when a second A: line is encountered.

I'd say the bug is the comment section of object.txt.

Multiple alloc lines might be a good idea, but to do it properly requires some familiarity with the codebase. In addition, I think that if it is done the alloc_prob[] should be changed to 32 bit variables at the same time.
PowerDiver is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Inconsistency in object.txt? Tiburon Silverflame Vanilla 14 May 22, 2010 14:45
object list possible bug PowerDiver Vanilla 14 February 2, 2010 16:16
Display price in object info? Tobias Vanilla 9 January 1, 2010 18:59
Obliterating k_idx from the savefiles and object.txt zaimoni Development 0 April 30, 2009 01:37
'object.txt' format suggestion PaulBlay Development 3 March 30, 2009 02:23


All times are GMT +1. The time now is 04:54.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.