--- deliantra/server/common/material.C 2009/11/10 16:29:20 1.7
+++ 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 (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)
@@ -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");
}