--- deliantra/server/common/material.C 2009/11/10 04:38:45 1.5
+++ 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,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");
}