| 148 | } |
| 149 | |
| 150 | void |
| 151 | init_objects(void) |
| 152 | { |
| 153 | int i, first, last, prevoclass; |
| 154 | char oclass; |
| 155 | |
| 156 | for (i = 0; i <= MAXOCLASSES; i++) { |
| 157 | svb.bases[i] = 0; |
| 158 | if (i > 0 && i < MAXOCLASSES && objects[i].oc_class != i) |
| 159 | panic( |
| 160 | "init_objects: class for generic object #%d doesn't match (%d)", |
| 161 | i, objects[i].oc_class); |
| 162 | } |
| 163 | /* initialize object descriptions */ |
| 164 | for (i = 0; i < NUM_OBJECTS; i++) |
| 165 | objects[i].oc_name_idx = objects[i].oc_descr_idx = i; |
| 166 | /* init base; if probs given check that they add up to 1000, |
| 167 | otherwise compute probs */ |
| 168 | first = MAXOCLASSES; |
| 169 | prevoclass = -1; |
| 170 | while (first < NUM_OBJECTS) { |
| 171 | oclass = objects[first].oc_class; |
| 172 | /* |
| 173 | * objects[] sanity check: must be in ascending oc_class order to |
| 174 | * be able to use bases[class+1]-1 for the end of a class's range. |
| 175 | * Also catches a non-contiguous class because reverting to any |
| 176 | * earlier class would involve switching back to a lower class |
| 177 | * number after having moved on to one or more other classes. |
| 178 | */ |
| 179 | if ((int) oclass < prevoclass) |
| 180 | panic("objects[%d] class #%d not in order!", first, oclass); |
| 181 | |
| 182 | last = first + 1; |
| 183 | while (last < NUM_OBJECTS && objects[last].oc_class == oclass) |
| 184 | last++; |
| 185 | svb.bases[(int) oclass] = first; |
| 186 | |
| 187 | if (oclass == GEM_CLASS) { |
| 188 | setgemprobs((d_level *) 0); |
| 189 | randomize_gem_colors(); |
| 190 | } |
| 191 | first = last; |
| 192 | prevoclass = (int) oclass; |
| 193 | } |
| 194 | /* extra entry allows deriving the range of a class via |
| 195 | bases[class] through bases[class+1]-1 for all classes |
| 196 | (except for ILLOBJ_CLASS which is separated from WEAPON_CLASS |
| 197 | by generic objects); second extra entry is to prevent an |
| 198 | unexplained crash in doclassdisco(), where the code ended up |
| 199 | attempting to process non-existent class MAXOCLASSES; the |
| 200 | [MAXOCLASSES+1] element gives that non-class 0 objects |
| 201 | when traversing objects[] from bases[X] through bases[X+1]-1 */ |
| 202 | svb.bases[MAXOCLASSES] = svb.bases[MAXOCLASSES + 1] = NUM_OBJECTS; |
| 203 | /* hypothetically someone might remove all objects of some class, |
| 204 | or be adding a new class and not populated it yet, leaving gaps |
| 205 | in bases[]; guarantee that there are no such gaps */ |
| 206 | for (last = MAXOCLASSES - 1; last >= 0; --last) |
| 207 | if (!svb.bases[last]) |
no test coverage detected