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.47 by root, Tue Apr 17 18:24:30 2007 UTC

128 } 128 }
129 129
130 tl->total_chance = 0; 130 tl->total_chance = 0;
131} 131}
132 132
133#ifdef TREASURE_DEBUG
134/* recursived checks the linked list. Treasurelist is passed only
135 * so that the treasure name can be printed out
136 */
137static void
138check_treasurelist (const treasure *t, const treasurelist * tl)
139{
140 if (t->chance >= 100 && t->next_yes && (t->next || t->next_no))
141 LOG (llevError, "Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", &tl->name);
142
143 if (t->next)
144 check_treasurelist (t->next, tl);
145
146 if (t->next_yes)
147 check_treasurelist (t->next_yes, tl);
148
149 if (t->next_no)
150 check_treasurelist (t->next_no, tl);
151}
152#endif
153
133/* 154/*
134 * Reads the lib/treasure file from disk, and parses the contents 155 * Reads the lib/treasure file from disk, and parses the contents
135 * into an internal treasure structure (very linked lists) 156 * into an internal treasure structure (very linked lists)
136 */ 157 */
137static treasure * 158static treasure *
138load_treasure (object_thawer &f) 159read_treasure (object_thawer &f)
139{ 160{
140 treasure *t = new treasure; 161 treasure *t = new treasure;
141 int value;
142 162
143 nroftreasures++; 163 f.next ();
144 164
145 for (;;) 165 for (;;)
146 { 166 {
147 coroapi::cede_to_tick_every (10); 167 coroapi::cede_to_tick_every (10);
148
149 f.next ();
150 168
151 switch (f.kw) 169 switch (f.kw)
152 { 170 {
153 case KW_arch: 171 case KW_arch:
154 if (!(t->item = archetype::find (f.get_str ()))) 172 if (!(t->item = archetype::find (f.get_str ())))
161 case KW_change_slaying: f.get (t->change_arch.slaying); break; 179 case KW_change_slaying: f.get (t->change_arch.slaying); break;
162 case KW_chance: f.get (t->chance); break; 180 case KW_chance: f.get (t->chance); break;
163 case KW_nrof: f.get (t->nrof); break; 181 case KW_nrof: f.get (t->nrof); break;
164 case KW_magic: f.get (t->magic); break; 182 case KW_magic: f.get (t->magic); break;
165 183
166 case KW_yes: t->next_yes = load_treasure (f); break; 184 case KW_yes: t->next_yes = read_treasure (f); continue;
167 case KW_no: t->next_no = load_treasure (f); break; 185 case KW_no: t->next_no = read_treasure (f); continue;
168 186
169 case KW_end: 187 case KW_end:
188 f.next ();
170 return t; 189 return t;
171 190
172 case KW_more: 191 case KW_more:
173 t->next = load_treasure (f); 192 t->next = read_treasure (f);
174 return t; 193 return t;
175 194
176 default: 195 default:
177 if (!f.parse_error ("treasure list")) 196 if (!f.parse_error ("treasurelist", t->name))
178 return t; // error 197 return 0;
179 198
180 return t; 199 return t;
181 } 200 }
182 }
183}
184 201
185#ifdef TREASURE_DEBUG 202 f.next ();
186/* recursived checks the linked list. Treasurelist is passed only 203 }
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} 204}
204#endif
205 205
206/* 206/*
207 * Opens LIBDIR/treasure and reads all treasure-declarations from it.
208 * Each treasure is parsed with the help of load_treasure(). 207 * Each treasure is parsed with the help of load_treasure().
209 */ 208 */
210bool 209treasurelist *
211load_treasure_file (const char *filename) 210treasurelist::read (object_thawer &f)
212{ 211{
213 treasure *t; 212 assert (f.kw == KW_treasure || f.kw == KW_treasureone);
214 int comp, line = 0;
215 213
216 object_thawer f (filename); 214 bool one = f.kw == KW_treasureone;
217 215 treasurelist *tl = treasurelist::get (f.get_str ());
218 if (!f) 216 clear (tl);
219 { 217 tl->items = read_treasure (f);
220 LOG (llevError, "Can't open treasure file.\n"); 218 if (!tl->items)
221 return false; 219 return 0;
220
221 /* This is a one of the many items on the list should be generated.
222 * Add up the chance total, and check to make sure the yes & no
223 * fields of the treasures are not being used.
224 */
225 tl->total_chance = 0;
226
227 if (one)
222 } 228 {
223 229 for (treasure *t = tl->items; t; t = t->next)
224 f.next ();
225
226 for (;;)
227 {
228 switch (f.kw)
229 { 230 {
230 case KW_treasure: 231 if (t->next_yes || t->next_no)
231 case KW_treasureone:
232 { 232 {
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); 233 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"); 234 LOG (llevError, " the next_yes or next_no field is set\n");
255 }
256#endif
257 tl->total_chance += t->chance;
258 }
259 }
260 } 235 }
261 break;
262 236
263 case KW_EOF: 237 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 } 238 }
281
282 f.next ();
283 } 239 }
240
241 return tl;
284} 242}
285 243
286/* 244/*
287 * Generates the objects specified by the given treasure. 245 * Generates the objects specified by the given treasure.
288 * It goes recursively through the rest of the linked list. 246 * It goes recursively through the rest of the linked list.
347 if ((int) t->chance >= 100 || (rndm (100) + 1) < (int) t->chance) 305 if ((int) t->chance >= 100 || (rndm (100) + 1) < (int) t->chance)
348 { 306 {
349 if (t->name) 307 if (t->name)
350 { 308 {
351 if (difficulty >= t->magic) 309 if (difficulty >= t->magic)
310 if (treasurelist *tl = treasurelist::find (t->name))
352 create_treasure (treasurelist::find (t->name), op, flag, difficulty, tries); 311 create_treasure (tl, op, flag, difficulty, tries);
312 else
313 LOG (llevError, "create_all_treasures: undefined reference to treasurelist '%s'.\n", &t->name);
353 } 314 }
354 else 315 else
355 { 316 {
356 if (t->item && (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE))) 317 if (t->item && (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE)))
357 { 318 {
1354 { 1315 {
1355 switch (f.kw) 1316 switch (f.kw)
1356 { 1317 {
1357 case KW_allowed: 1318 case KW_allowed:
1358 if (!art) 1319 if (!art)
1359 {
1360 art = get_empty_artifact (); 1320 art = get_empty_artifact ();
1361 nrofartifacts++;
1362 }
1363 1321
1364 { 1322 {
1365 if (!strcmp (f.get_str (), "all")) 1323 if (!strcmp (f.get_str (), "all"))
1366 break; 1324 break;
1367 1325
1368 char *next, *cp = f.get_str (); 1326 char *next, *cp = f.get_str ();
1369 1327
1370 do 1328 do
1371 { 1329 {
1372 nrofallowedstr++;
1373
1374 if ((next = strchr (cp, ','))) 1330 if ((next = strchr (cp, ',')))
1375 *next++ = '\0'; 1331 *next++ = '\0';
1376 1332
1377 linked_char *tmp = new linked_char; 1333 linked_char *tmp = new linked_char;
1378 1334
1428 } 1384 }
1429 1385
1430done: 1386done:
1431 for (al = first_artifactlist; al; al = al->next) 1387 for (al = first_artifactlist; al; al = al->next)
1432 { 1388 {
1389 al->total_chance = 0;
1390
1433 for (art = al->items; art; art = art->next) 1391 for (art = al->items; art; art = art->next)
1434 { 1392 {
1435 if (!art->chance) 1393 if (!art->chance)
1436 LOG (llevError, "Warning: artifact with no chance: %s\n", &art->item->name); 1394 LOG (llevError, "Warning: artifact with no chance: %s\n", &art->item->name);
1437 else 1395 else
1443 } 1401 }
1444 1402
1445 LOG (llevDebug, "done.\n"); 1403 LOG (llevDebug, "done.\n");
1446} 1404}
1447 1405
1448
1449/* 1406/*
1450 * Used in artifact generation. The bonuses of the first object 1407 * Used in artifact generation. The bonuses of the first object
1451 * is modified by the bonuses of the second object. 1408 * is modified by the bonuses of the second object.
1452 */ 1409 */
1453
1454void 1410void
1455add_abilities (object *op, object *change) 1411add_abilities (object *op, object *change)
1456{ 1412{
1457 int i, tmp; 1413 int i, tmp;
1458 1414
1811 SET_FLAG (item, FLAG_NO_STEAL); 1767 SET_FLAG (item, FLAG_NO_STEAL);
1812 } 1768 }
1813} 1769}
1814 1770
1815/* special_potion() - so that old potion code is still done right. */ 1771/* special_potion() - so that old potion code is still done right. */
1816
1817int 1772int
1818special_potion (object *op) 1773special_potion (object *op)
1819{ 1774{
1820 if (op->attacktype) 1775 if (op->attacktype)
1821 return 1; 1776 return 1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines