--- deliantra/server/common/material.C 2009/11/10 00:01:31 1.4 +++ deliantra/server/common/material.C 2010/04/15 21:49:15 1.12 @@ -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 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 @@ -27,16 +27,80 @@ //+GPL -/* convert materialname to materialtype_t */ +materialtype_t *materialt; + +/* +materialtype material[NROFMATERIALS] = { + * P M F E C C A D W G P S P T F C D D C C G H B I * + * H A I L O O C R E H O L A U E A E E H O O O L N * + * Y G R E L N I A A O I O R R A N P A A U D L I T * + * S I E C D F D I P S S W A N R C L T O N Y N R * + * I C T U N O T O L E E H S T P D N * + {"paper", {15,10,17, 9, 5, 7,13, 0,20,15, 0,0,0,0,0,10,0,0,0,0,0,0,0,0}}, + {"metal", { 2,12, 3,12, 2,10, 7, 0,20,15, 0,0,0,0,0,10,0,0,0,0,0,0,0,0}}, + {"glass", {14,11, 8, 3,10, 5, 1, 0,20,15, 0,0,0,0,0, 0,0,0,0,0,0,0,0,0}}, + {"leather", { 5,10,10, 3, 3,10,10, 0,20,15, 0,0,0,0,0,12,0,0,0,0,0,0,0,0}}, + {"wood", {10,11,13, 2, 2,10, 9, 0,20,15, 0,0,0,0,0,12,0,0,0,0,0,0,0,0}}, + {"organics", { 3,12, 9,11, 3,10, 9, 0,20,15, 0,0,0,0,0, 0,0,0,0,0,0,0,0,0}}, + {"stone", { 2, 5, 2, 2, 2, 2, 1, 0,20,15, 0,0,0,0,0, 5,0,0,0,0,0,0,0,0}}, + {"cloth", {14,11,13, 4, 4, 5,10, 0,20,15, 0,0,0,0,0, 5,0,0,0,0,0,0,0,0}}, + {"adamant", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0, 0,0,0,0,0,0,0,0,0}}, + {"liquid", { 0, 8, 9, 6,17, 0,15, 0,20,15,12,0,0,0,0,11,0,0,0,0,0,0,0,0}}, + {"soft metal",{ 6,12, 6,14, 2,10, 1, 0,20,15, 0,0,0,0,0,10,0,0,0,0,0,0,0,0}}, + {"bone", {10, 9, 4, 5, 3,10,10, 0,20,15, 0,0,0,0,0, 2,0,0,0,0,0,0,0,0}}, + {"ice", {14,11,16, 5, 0, 5, 6, 0,20,15, 0,0,0,0,0, 7,0,0,0,0,0,0,0,0}} +}; +*/ + +materialtype_t::materialtype_t () +{ + next = 0; + name = shstr_unknown; + description = shstr_unknown_material_description; + material = 0; + + for (int i = 0; i < NROFATTACKS; i++) + { + save [i] = 0; + mod [i] = 0; + } + + chance = 0; + difficulty = 0; + magic = 0; + damage = 0; + wc = 0; + ac = 0; + sp = 0; + weight = 100; + value = 100; + density = 1000; +} +/* convert materialname to materialtype_t */ materialtype_t * -name_to_material (const shstr_cmp name) +name_to_material (const shstr_tmp name) { for (materialtype_t *mt = materialt; mt; mt = mt->next) if (name == mt->name) return mt; - return 0; + 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; + + // 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; } /* when doing transmutation of objects, we have to recheck the resistances, @@ -45,60 +109,48 @@ void transmute_materialname (object *op, const object *change) { - materialtype_t *mt; - int j; - - if (!op->materialname) + if (!op->is_armor ()) return; - if (op->materialname != change->materialname) + if (op->material == MATERIAL_NULL) return; - if (!op->is_armor ()) + if (op->material != change->material) return; - mt = name_to_material (op->materialname); - if (!mt) - { - LOG (llevError, "archetype '%s>%s' uses nonexistent material '%s'\n", &op->arch->archname, &op->name, &op->materialname); - 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]; - if (op->resist[j] > 100) - op->resist[j] = 100; - if (op->resist[j] < -100) - op->resist[j] = -100; + + if (op->resist[j] > 100) op->resist[j] = 100; + if (op->resist[j] < -100) op->resist[j] = -100; } } /* set the materialname and type for an item */ void -set_materialname (object *op, int difficulty, materialtype_t *nmt) +select_material (object *op, int difficulty) { - materialtype_t *mt, *lmt; - - if (!op->materialname) + if (op->material != MATERIAL_NULL || !op->materials) return; - if (nmt) - lmt = nmt; - else - { - lmt = 0; + materialtype_t *lmt = 0; - for (mt = materialt; mt; mt = mt->next) - if (op->materials & mt->material && rndm (1, 100) <= mt->chance && - difficulty >= mt->difficulty && (op->magic >= mt->magic || mt->magic == 0)) - { - lmt = mt; - if (!(op->is_weapon () || op->is_armor ())) - break; - } - } + //TODL: dead code? + for (materialtype_t *mt = materialt; mt; mt = mt->next) + if (op->materials & mt->material + && difficulty >= mt->difficulty + && rndm (1, 100) <= mt->chance + && (op->magic >= mt->magic || mt->magic == 0)) + { + lmt = mt; + + if (!(op->is_weapon () || op->is_armor ())) + break; + } if (lmt) { @@ -109,10 +161,9 @@ op->stats.dam = 1; } - if (op->stats.sp && op->type == BOW) - op->stats.sp += lmt->sp; - if (op->stats.wc && op->is_weapon ()) - op->stats.wc += lmt->wc; + if (op->stats.sp && op->type == BOW ) op->stats.sp += lmt->sp; + if (op->stats.wc && op->is_weapon ()) op->stats.wc += lmt->wc; + if (op->is_armor ()) { if (op->stats.ac) @@ -122,69 +173,26 @@ if (op->resist[j] != 0) { op->resist[j] += lmt->mod[j]; - if (op->resist[j] > 100) - op->resist[j] = 100; - if (op->resist[j] < -100) - op->resist[j] = -100; + if (op->resist[j] > 100) op->resist[j] = 100; + if (op->resist[j] < -100) op->resist[j] = -100; } } - op->materialname = lmt->name; + op->material = lmt; + /* dont make it unstackable if it doesn't need to be */ if (op->is_weapon () || op->is_armor ()) { - op->weight = (op->weight * lmt->weight) / 100; - op->value = (op->value * lmt->value) / 100; + op->weight = op->weight * lmt->weight / 100; + op->value = op->value * lmt->value / 100; } } } -//TODO: make this a constructor -static materialtype_t * -get_empty_mat (void) -{ - materialtype_t *mt; - int i; - - mt = new materialtype_t; - - mt->name = shstr_unknown; - mt->description = 0; - - for (i = 0; i < NROFATTACKS; i++) - { - mt->save[i] = 0; - mt->mod[i] = 0; - } - - mt->chance = 0; - mt->difficulty = 0; - mt->magic = 0; - mt->damage = 0; - mt->wc = 0; - mt->ac = 0; - mt->sp = 0; - mt->weight = 100; - mt->value = 100; - mt->density = 1; - mt->next = 0; - - return mt; -} - //-GPL -const materialtype_t * -object::dominant_material () const -{ - if (materialtype_t *mt = name_to_material (materialname)) - return mt; - - return name_to_material (shstr_unknown); -} - void -load_materials (void) +load_materials () { char filename[MAX_BUF]; @@ -192,7 +200,8 @@ LOG (llevDebug, "Reading material type data from %s...\n", filename); //TODO: somehow free old materials, or update them in-place - materialt = 0; + // currently we effectively leak them. + material_null.next = 0; materialt = &material_null; object_thawer thawer (filename); @@ -217,12 +226,11 @@ switch (thawer.kw) { case KW_name: - mt = get_empty_mat (); - mt->next = materialt; - materialt = mt; - + mt = new materialtype_t; thawer.get (mt->name); mt->description = mt->name; + + mt->next = materialt; materialt = mt; break; case KW_description: @@ -292,7 +300,7 @@ goto done; default: - if (!thawer.parse_error ("materials file", "materials")) + if (!thawer.parse_error ("materials file")) goto done; break; } @@ -301,9 +309,6 @@ } done: - if (!materialt) - materialt = get_empty_mat (); - LOG (llevDebug, "Done.\n"); }