--- deliantra/server/common/material.C 2009/11/10 04:38:45 1.5 +++ deliantra/server/common/material.C 2011/04/23 04:56:46 1.16 @@ -1,9 +1,9 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. * - * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team - * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team - * Copyright (©) 1992,2007 Frank Tore Johansen + * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * Copyright (©) 2002 Mark Wedel & Crossfire Development Team + * Copyright (©) 1992 Frank Tore Johansen * * Deliantra is free software: you can redistribute it and/or modify it under * the terms of the Affero GNU General Public License as published by the @@ -54,15 +54,21 @@ materialtype_t::materialtype_t () { - next = 0; + next = 0; + reset (); +} + +void +materialtype_t::reset () +{ name = shstr_unknown; description = shstr_unknown_material_description; material = 0; for (int i = 0; i < NROFATTACKS; i++) { - save [i] = 10; - mod [i] = 9; + save [i] = 0; + mod [i] = 0; } chance = 0; @@ -77,43 +83,83 @@ density = 1000; } -/* convert materialname to materialtype_t */ -materialtype_t * -name_to_material (const shstr_tmp name) +// create a new material of the given name +static materialtype_t * +dummy_material (shstr_tmp name) +{ + materialtype_t *mt = new materialtype_t; + mt->name = name; + + // make it susceptible to attacks + for (int i = 0; i < NROFATTACKS; i++) + { + mt->save [i] = 10; + mt->mod [i] = 9; + } + + mt->next = materialt; materialt = mt; + + return mt; +} + +static materialtype_t * +find (const shstr_tmp name) { for (materialtype_t *mt = materialt; mt; mt = mt->next) if (name == mt->name) return mt; - LOG (llevError, "name_to_material called with nonexistent material '%s'\n", &name); + return 0; +} - // create a new material of the given name - materialtype_t *mt = new materialtype_t; - mt->name = name; +/* convert materialname to materialtype_t */ +materialtype_t * +name_to_material (const shstr_tmp name) +{ + materialtype_t *mt = find (name); - mt->next = materialt; - materialt = mt; + if (!mt) + { + LOG (llevError, "name_to_material called with nonexistent material '%s'\n", &name); + mt = dummy_material (name); + } return mt; } +void +object_thawer::get (materialtype_t *&mt) const +{ + shstr name; + get (name); + + mt = find (name); + + if (!mt) + { + parse_error (format ("material called %s requested, but not found, creating dummy material.\n", &name)); + mt = dummy_material (name); + } +} + /* when doing transmutation of objects, we have to recheck the resistances, * as some that did not apply previously, may apply now. */ void transmute_materialname (object *op, const object *change) { - int j; + if (!op->is_armor ()) + return; - if (op->material != change->material) + if (op->material == MATERIAL_NULL) return; - if (!op->is_armor ()) + if (op->material != change->material) return; materialtype_t *mt = op->material; - for (j = 0; j < NROFATTACKS; j++) + for (int j = 0; j < NROFATTACKS; j++) if (op->resist[j] == 0 && change->resist[j] != 0) { op->resist[j] += mt->mod[j]; @@ -127,7 +173,7 @@ void select_material (object *op, int difficulty) { - if (op->material != &material_null || !op->materials) + if (op->material != MATERIAL_NULL || !op->materials) return; materialtype_t *lmt = 0; @@ -185,23 +231,14 @@ //-GPL void -load_materials (void) +reload_materials () { - char filename[MAX_BUF]; - - sprintf (filename, "%s/materials", settings.datadir); - LOG (llevDebug, "Reading material type data from %s...\n", filename); - - //TODO: somehow free old materials, or update them in-place - material_null.next = 0; - materialt = &material_null; - - object_thawer thawer (filename); + object_thawer thawer (settings.datadir, "materials"); if (!thawer) { - LOG (llevError, "Cannot open %s for reading\n", filename); - goto done; + LOG (llevError, "unable to load %s for reading\n", thawer.name); + return; } while (thawer.kw != KW_name) @@ -209,7 +246,7 @@ thawer.next (); if (thawer.kw == KW_EOF) - goto done; + return; } materialtype_t *mt; @@ -219,12 +256,26 @@ switch (thawer.kw) { case KW_name: - mt = new materialtype_t; - thawer.get (mt->name); - mt->description = mt->name; + coroapi::cede_to_tick (); + + { + // create a new dummy material, or find the existing material + shstr name; + thawer.get (name); + + mt = find (name); + + if (mt) + mt->reset (); + else + { + mt = new materialtype_t; + mt->next = materialt; materialt = mt; + } - mt->next = materialt; - materialt = mt; + mt->name = name; + mt->description = name; + } break; case KW_description: @@ -291,21 +342,15 @@ case KW_density: thawer.get (mt->density); break; case KW_EOF: - goto done; + return; default: - if (!thawer.parse_error ("materials file", "materials")) - goto done; + if (!thawer.parse_error ("materials file")) + return; break; } thawer.next (); } - -done: - if (!materialt) - materialt = new materialtype_t; - - LOG (llevDebug, "Done.\n"); }