ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/treasure.C
(Generate patch)

Comparing deliantra/server/common/treasure.C (file contents):
Revision 1.46 by root, Tue Apr 17 10:06:32 2007 UTC vs.
Revision 1.48 by root, Tue Apr 17 18:40:31 2007 UTC

54> tl_map_t; 54> tl_map_t;
55 55
56static tl_map_t tl_map; 56static tl_map_t tl_map;
57 57
58/* 58/*
59 * Initialize global archtype pointers:
60 */
61void
62init_archetype_pointers ()
63{
64 int prev_warn = warn_archetypes;
65
66 warn_archetypes = 1;
67
68 if (ring_arch == NULL)
69 ring_arch = archetype::find ("ring");
70 if (amulet_arch == NULL)
71 amulet_arch = archetype::find ("amulet");
72 if (staff_arch == NULL)
73 staff_arch = archetype::find ("staff");
74 if (crown_arch == NULL)
75 crown_arch = archetype::find ("crown");
76
77 warn_archetypes = prev_warn;
78}
79
80/*
81 * Searches for the given treasurelist 59 * Searches for the given treasurelist
82 */ 60 */
83treasurelist * 61treasurelist *
84treasurelist::find (const char *name) 62treasurelist::find (const char *name)
85{ 63{
128 } 106 }
129 107
130 tl->total_chance = 0; 108 tl->total_chance = 0;
131} 109}
132 110
111#ifdef TREASURE_DEBUG
112/* recursived checks the linked list. Treasurelist is passed only
113 * so that the treasure name can be printed out
114 */
115static void
116check_treasurelist (const treasure *t, const treasurelist * tl)
117{
118 if (t->chance >= 100 && t->next_yes && (t->next || t->next_no))
119 LOG (llevError, "Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", &tl->name);
120
121 if (t->next)
122 check_treasurelist (t->next, tl);
123
124 if (t->next_yes)
125 check_treasurelist (t->next_yes, tl);
126
127 if (t->next_no)
128 check_treasurelist (t->next_no, tl);
129}
130#endif
131
133/* 132/*
134 * Reads the lib/treasure file from disk, and parses the contents 133 * Reads the lib/treasure file from disk, and parses the contents
135 * into an internal treasure structure (very linked lists) 134 * into an internal treasure structure (very linked lists)
136 */ 135 */
137static treasure * 136static treasure *
138load_treasure (object_thawer &f) 137read_treasure (object_thawer &f)
139{ 138{
140 treasure *t = new treasure; 139 treasure *t = new treasure;
141 int value;
142 140
143 nroftreasures++; 141 f.next ();
144 142
145 for (;;) 143 for (;;)
146 { 144 {
147 coroapi::cede_to_tick_every (10); 145 coroapi::cede_to_tick_every (10);
148
149 f.next ();
150 146
151 switch (f.kw) 147 switch (f.kw)
152 { 148 {
153 case KW_arch: 149 case KW_arch:
154 if (!(t->item = archetype::find (f.get_str ()))) 150 if (!(t->item = archetype::find (f.get_str ())))
161 case KW_change_slaying: f.get (t->change_arch.slaying); break; 157 case KW_change_slaying: f.get (t->change_arch.slaying); break;
162 case KW_chance: f.get (t->chance); break; 158 case KW_chance: f.get (t->chance); break;
163 case KW_nrof: f.get (t->nrof); break; 159 case KW_nrof: f.get (t->nrof); break;
164 case KW_magic: f.get (t->magic); break; 160 case KW_magic: f.get (t->magic); break;
165 161
166 case KW_yes: t->next_yes = load_treasure (f); break; 162 case KW_yes: t->next_yes = read_treasure (f); continue;
167 case KW_no: t->next_no = load_treasure (f); break; 163 case KW_no: t->next_no = read_treasure (f); continue;
168 164
169 case KW_end: 165 case KW_end:
166 f.next ();
170 return t; 167 return t;
171 168
172 case KW_more: 169 case KW_more:
173 t->next = load_treasure (f); 170 t->next = read_treasure (f);
174 return t; 171 return t;
175 172
176 default: 173 default:
177 if (!f.parse_error ("treasure list")) 174 if (!f.parse_error ("treasurelist", t->name))
178 return t; // error 175 return 0;
179 176
180 return t; 177 return t;
181 } 178 }
182 }
183}
184 179
185#ifdef TREASURE_DEBUG 180 f.next ();
186/* recursived checks the linked list. Treasurelist is passed only 181 }
187 * so that the treasure name can be printed out
188 */
189static void
190check_treasurelist (const treasure *t, const treasurelist * tl)
191{
192 if (t->chance >= 100 && t->next_yes && (t->next || t->next_no))
193 LOG (llevError, "Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", &tl->name);
194
195 if (t->next)
196 check_treasurelist (t->next, tl);
197
198 if (t->next_yes)
199 check_treasurelist (t->next_yes, tl);
200
201 if (t->next_no)
202 check_treasurelist (t->next_no, tl);
203} 182}
204#endif
205 183
206/* 184/*
207 * Opens LIBDIR/treasure and reads all treasure-declarations from it.
208 * Each treasure is parsed with the help of load_treasure(). 185 * Each treasure is parsed with the help of load_treasure().
209 */ 186 */
210bool 187treasurelist *
211load_treasure_file (const char *filename) 188treasurelist::read (object_thawer &f)
212{ 189{
213 treasure *t; 190 assert (f.kw == KW_treasure || f.kw == KW_treasureone);
214 int comp, line = 0;
215 191
216 object_thawer f (filename); 192 bool one = f.kw == KW_treasureone;
217 193 treasurelist *tl = treasurelist::get (f.get_str ());
218 if (!f) 194 clear (tl);
219 { 195 tl->items = read_treasure (f);
220 LOG (llevError, "Can't open treasure file.\n"); 196 if (!tl->items)
221 return false; 197 return 0;
198
199 /* This is a one of the many items on the list should be generated.
200 * Add up the chance total, and check to make sure the yes & no
201 * fields of the treasures are not being used.
202 */
203 tl->total_chance = 0;
204
205 if (one)
222 } 206 {
223 207 for (treasure *t = tl->items; t; t = t->next)
224 f.next ();
225
226 for (;;)
227 {
228 switch (f.kw)
229 { 208 {
230 case KW_treasure: 209 if (t->next_yes || t->next_no)
231 case KW_treasureone:
232 { 210 {
233 bool one = f.kw == KW_treasureone;
234 treasurelist *tl = treasurelist::get (f.get_str ());
235
236 clear (tl);
237 tl->items = load_treasure (f);
238
239 if (!tl->items)
240 return false;
241
242 /* This is a one of the many items on the list should be generated.
243 * Add up the chance total, and check to make sure the yes & no
244 * fields of the treasures are not being used.
245 */
246 if (one)
247 {
248 for (t = tl->items; t; t = t->next)
249 {
250#ifdef TREASURE_DEBUG
251 if (t->next_yes || t->next_no)
252 {
253 LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name); 211 LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name);
254 LOG (llevError, " the next_yes or next_no field is set\n"); 212 LOG (llevError, " the next_yes or next_no field is set\n");
255 }
256#endif
257 tl->total_chance += t->chance;
258 }
259 }
260 } 213 }
261 break;
262 214
263 case KW_EOF: 215 tl->total_chance += t->chance;
264#ifdef TREASURE_DEBUG
265 /* Perform some checks on how valid the treasure data actually is.
266 * verify that list transitions work (ie, the list that it is supposed
267 * to transition to exists). Also, verify that at least the name
268 * or archetype is set for each treasure element.
269 */
270 for (treasurelist *tl = first_treasurelist; tl; tl = tl->next)
271 check_treasurelist (tl->items, tl);
272#endif
273 return true;
274
275 default:
276 if (!f.parse_error ("treasure lists"))
277 return false;
278
279 break;
280 } 216 }
281
282 f.next ();
283 } 217 }
218
219 return tl;
284} 220}
285 221
286/* 222/*
287 * Generates the objects specified by the given treasure. 223 * Generates the objects specified by the given treasure.
288 * It goes recursively through the rest of the linked list. 224 * It goes recursively through the rest of the linked list.
347 if ((int) t->chance >= 100 || (rndm (100) + 1) < (int) t->chance) 283 if ((int) t->chance >= 100 || (rndm (100) + 1) < (int) t->chance)
348 { 284 {
349 if (t->name) 285 if (t->name)
350 { 286 {
351 if (difficulty >= t->magic) 287 if (difficulty >= t->magic)
288 if (treasurelist *tl = treasurelist::find (t->name))
352 create_treasure (treasurelist::find (t->name), op, flag, difficulty, tries); 289 create_treasure (tl, op, flag, difficulty, tries);
290 else
291 LOG (llevError, "create_all_treasures: undefined reference to treasurelist '%s'.\n", &t->name);
353 } 292 }
354 else 293 else
355 { 294 {
356 if (t->item && (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE))) 295 if (t->item && (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE)))
357 { 296 {
1354 { 1293 {
1355 switch (f.kw) 1294 switch (f.kw)
1356 { 1295 {
1357 case KW_allowed: 1296 case KW_allowed:
1358 if (!art) 1297 if (!art)
1359 {
1360 art = get_empty_artifact (); 1298 art = get_empty_artifact ();
1361 nrofartifacts++;
1362 }
1363 1299
1364 { 1300 {
1365 if (!strcmp (f.get_str (), "all")) 1301 if (!strcmp (f.get_str (), "all"))
1366 break; 1302 break;
1367 1303
1368 char *next, *cp = f.get_str (); 1304 char *next, *cp = f.get_str ();
1369 1305
1370 do 1306 do
1371 { 1307 {
1372 nrofallowedstr++;
1373
1374 if ((next = strchr (cp, ','))) 1308 if ((next = strchr (cp, ',')))
1375 *next++ = '\0'; 1309 *next++ = '\0';
1376 1310
1377 linked_char *tmp = new linked_char; 1311 linked_char *tmp = new linked_char;
1378 1312
1428 } 1362 }
1429 1363
1430done: 1364done:
1431 for (al = first_artifactlist; al; al = al->next) 1365 for (al = first_artifactlist; al; al = al->next)
1432 { 1366 {
1367 al->total_chance = 0;
1368
1433 for (art = al->items; art; art = art->next) 1369 for (art = al->items; art; art = art->next)
1434 { 1370 {
1435 if (!art->chance) 1371 if (!art->chance)
1436 LOG (llevError, "Warning: artifact with no chance: %s\n", &art->item->name); 1372 LOG (llevError, "Warning: artifact with no chance: %s\n", &art->item->name);
1437 else 1373 else
1443 } 1379 }
1444 1380
1445 LOG (llevDebug, "done.\n"); 1381 LOG (llevDebug, "done.\n");
1446} 1382}
1447 1383
1448
1449/* 1384/*
1450 * Used in artifact generation. The bonuses of the first object 1385 * Used in artifact generation. The bonuses of the first object
1451 * is modified by the bonuses of the second object. 1386 * is modified by the bonuses of the second object.
1452 */ 1387 */
1453
1454void 1388void
1455add_abilities (object *op, object *change) 1389add_abilities (object *op, object *change)
1456{ 1390{
1457 int i, tmp; 1391 int i, tmp;
1458 1392
1811 SET_FLAG (item, FLAG_NO_STEAL); 1745 SET_FLAG (item, FLAG_NO_STEAL);
1812 } 1746 }
1813} 1747}
1814 1748
1815/* special_potion() - so that old potion code is still done right. */ 1749/* special_potion() - so that old potion code is still done right. */
1816
1817int 1750int
1818special_potion (object *op) 1751special_potion (object *op)
1819{ 1752{
1820 if (op->attacktype) 1753 if (op->attacktype)
1821 return 1; 1754 return 1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines