--- deliantra/server/common/material.C 2009/11/29 10:55:18 1.8 +++ deliantra/server/common/material.C 2012/11/04 01:01:13 1.19 @@ -1,24 +1,24 @@ /* * 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,2012 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 * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the Affero GNU General Public License * and the GNU General Public License along with this program. If not, see * . - * + * * The authors can be reached via e-mail to */ @@ -54,7 +54,13 @@ materialtype_t::materialtype_t () { - next = 0; + next = 0; + reset (); +} + +void +materialtype_t::reset () +{ name = shstr_unknown; description = shstr_unknown_material_description; material = 0; @@ -77,17 +83,10 @@ 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) { - 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); - - // create a new material of the given name materialtype_t *mt = new materialtype_t; mt->name = name; @@ -103,6 +102,46 @@ 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; + + return 0; +} + +/* convert materialname to materialtype_t */ +materialtype_t * +name_to_material (const shstr_tmp name) +{ + materialtype_t *mt = find (name); + + 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. */ @@ -192,22 +231,14 @@ //-GPL void -load_materials () +_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) @@ -215,7 +246,7 @@ thawer.next (); if (thawer.kw == KW_EOF) - goto done; + return; } materialtype_t *mt; @@ -225,11 +256,26 @@ switch (thawer.kw) { case KW_name: - mt = new materialtype_t; - thawer.get (mt->name); - mt->description = mt->name; + coroapi::cede_to_tick (); - mt->next = materialt; materialt = mt; + { + // 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->name = name; + mt->description = name; + } break; case KW_description: @@ -296,18 +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: - LOG (llevDebug, "Done.\n"); }