ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/material.C
Revision: 1.21
Committed: Sat Nov 17 23:40:00 2018 UTC (5 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.20: +1 -0 lines
Log Message:
copyright update 2018

File Contents

# User Rev Content
1 root 1.1 /*
2     * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 root 1.18 *
4 root 1.21 * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
5 root 1.20 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
6 root 1.9 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
7     * Copyright (©) 1992 Frank Tore Johansen
8 root 1.18 *
9 root 1.1 * Deliantra is free software: you can redistribute it and/or modify it under
10     * the terms of the Affero GNU General Public License as published by the
11     * Free Software Foundation, either version 3 of the License, or (at your
12     * option) any later version.
13 root 1.18 *
14 root 1.1 * This program is distributed in the hope that it will be useful,
15     * but WITHOUT ANY WARRANTY; without even the implied warranty of
16     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17     * GNU General Public License for more details.
18 root 1.18 *
19 root 1.1 * You should have received a copy of the Affero GNU General Public License
20     * and the GNU General Public License along with this program. If not, see
21     * <http://www.gnu.org/licenses/>.
22 root 1.18 *
23 root 1.1 * The authors can be reached via e-mail to <support@deliantra.net>
24     */
25    
26     #include <global.h>
27     #include <material.h>
28    
29 root 1.3 //+GPL
30    
31 root 1.5 materialtype_t *materialt;
32    
33     /*
34     materialtype material[NROFMATERIALS] = {
35     * P M F E C C A D W G P S P T F C D D C C G H B I *
36     * H A I L O O C R E H O L A U E A E E H O O O L N *
37     * Y G R E L N I A A O I O R R A N P A A U D L I T *
38     * S I E C D F D I P S S W A N R C L T O N Y N R *
39     * I C T U N O T O L E E H S T P D N *
40     {"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}},
41     {"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}},
42     {"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}},
43     {"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}},
44     {"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}},
45     {"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}},
46     {"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}},
47     {"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}},
48     {"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}},
49     {"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}},
50     {"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}},
51     {"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}},
52     {"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}}
53     };
54     */
55    
56     materialtype_t::materialtype_t ()
57     {
58 root 1.15 next = 0;
59     reset ();
60     }
61    
62     void
63     materialtype_t::reset ()
64     {
65 root 1.5 name = shstr_unknown;
66     description = shstr_unknown_material_description;
67     material = 0;
68    
69     for (int i = 0; i < NROFATTACKS; i++)
70     {
71 root 1.6 save [i] = 0;
72     mod [i] = 0;
73 root 1.5 }
74    
75     chance = 0;
76     difficulty = 0;
77     magic = 0;
78     damage = 0;
79     wc = 0;
80     ac = 0;
81     sp = 0;
82     weight = 100;
83     value = 100;
84     density = 1000;
85     }
86    
87 root 1.14 // create a new material of the given name
88     static materialtype_t *
89     dummy_material (shstr_tmp name)
90 root 1.1 {
91 root 1.5 materialtype_t *mt = new materialtype_t;
92     mt->name = name;
93    
94 root 1.6 // make it susceptible to attacks
95     for (int i = 0; i < NROFATTACKS; i++)
96     {
97     mt->save [i] = 10;
98     mt->mod [i] = 9;
99     }
100    
101     mt->next = materialt; materialt = mt;
102 root 1.5
103     return mt;
104 root 1.1 }
105    
106 root 1.15 static materialtype_t *
107     find (const shstr_tmp name)
108     {
109     for (materialtype_t *mt = materialt; mt; mt = mt->next)
110     if (name == mt->name)
111     return mt;
112    
113     return 0;
114     }
115    
116 root 1.14 /* convert materialname to materialtype_t */
117     materialtype_t *
118     name_to_material (const shstr_tmp name)
119     {
120 root 1.15 materialtype_t *mt = find (name);
121 root 1.14
122 root 1.15 if (!mt)
123     {
124     LOG (llevError, "name_to_material called with nonexistent material '%s'\n", &name);
125     mt = dummy_material (name);
126     }
127 root 1.14
128 root 1.15 return mt;
129 root 1.14 }
130    
131     void
132 root 1.15 object_thawer::get (materialtype_t *&mt) const
133 root 1.14 {
134     shstr name;
135     get (name);
136    
137 root 1.15 mt = find (name);
138 root 1.14
139 root 1.15 if (!mt)
140     {
141     parse_error (format ("material called %s requested, but not found, creating dummy material.\n", &name));
142     mt = dummy_material (name);
143     }
144 root 1.14 }
145    
146 root 1.1 /* when doing transmutation of objects, we have to recheck the resistances,
147     * as some that did not apply previously, may apply now.
148     */
149     void
150     transmute_materialname (object *op, const object *change)
151     {
152 root 1.6 if (!op->is_armor ())
153     return;
154 root 1.1
155 root 1.7 if (op->material == MATERIAL_NULL)
156 root 1.1 return;
157    
158 root 1.6 if (op->material != change->material)
159 root 1.1 return;
160    
161 root 1.5 materialtype_t *mt = op->material;
162 root 1.1
163 root 1.6 for (int j = 0; j < NROFATTACKS; j++)
164 root 1.1 if (op->resist[j] == 0 && change->resist[j] != 0)
165     {
166     op->resist[j] += mt->mod[j];
167 root 1.5
168     if (op->resist[j] > 100) op->resist[j] = 100;
169     if (op->resist[j] < -100) op->resist[j] = -100;
170 root 1.1 }
171     }
172    
173     /* set the materialname and type for an item */
174     void
175 root 1.5 select_material (object *op, int difficulty)
176 root 1.1 {
177 root 1.7 if (op->material != MATERIAL_NULL || !op->materials)
178 root 1.5 return;
179 root 1.1
180 root 1.5 materialtype_t *lmt = 0;
181 root 1.1
182 root 1.5 //TODL: dead code?
183     for (materialtype_t *mt = materialt; mt; mt = mt->next)
184     if (op->materials & mt->material
185     && difficulty >= mt->difficulty
186     && rndm (1, 100) <= mt->chance
187     && (op->magic >= mt->magic || mt->magic == 0))
188     {
189     lmt = mt;
190 root 1.1
191 root 1.5 if (!(op->is_weapon () || op->is_armor ()))
192     break;
193     }
194 root 1.1
195     if (lmt)
196     {
197     if (op->stats.dam && op->is_weapon ())
198     {
199     op->stats.dam += lmt->damage;
200     if (op->stats.dam < 1)
201     op->stats.dam = 1;
202     }
203    
204 root 1.5 if (op->stats.sp && op->type == BOW ) op->stats.sp += lmt->sp;
205     if (op->stats.wc && op->is_weapon ()) op->stats.wc += lmt->wc;
206    
207 root 1.1 if (op->is_armor ())
208     {
209     if (op->stats.ac)
210     op->stats.ac += lmt->ac;
211    
212     for (int j = 0; j < NROFATTACKS; j++)
213     if (op->resist[j] != 0)
214     {
215     op->resist[j] += lmt->mod[j];
216 root 1.5 if (op->resist[j] > 100) op->resist[j] = 100;
217     if (op->resist[j] < -100) op->resist[j] = -100;
218 root 1.1 }
219     }
220    
221 root 1.5 op->material = lmt;
222    
223 root 1.1 /* dont make it unstackable if it doesn't need to be */
224     if (op->is_weapon () || op->is_armor ())
225     {
226 root 1.5 op->weight = op->weight * lmt->weight / 100;
227     op->value = op->value * lmt->value / 100;
228 root 1.1 }
229     }
230     }
231    
232 root 1.3 //-GPL
233    
234 root 1.2 void
235 root 1.19 _reload_materials ()
236 root 1.2 {
237 root 1.13 object_thawer thawer (settings.datadir, "materials");
238 root 1.2
239     if (!thawer)
240     {
241 root 1.15 LOG (llevError, "unable to load %s for reading\n", thawer.name);
242     return;
243 root 1.2 }
244    
245     while (thawer.kw != KW_name)
246     {
247     thawer.next ();
248    
249     if (thawer.kw == KW_EOF)
250 root 1.15 return;
251 root 1.2 }
252    
253     materialtype_t *mt;
254    
255     for (;;)
256     {
257     switch (thawer.kw)
258     {
259     case KW_name:
260 root 1.15 coroapi::cede_to_tick ();
261    
262     {
263     // create a new dummy material, or find the existing material
264     shstr name;
265     thawer.get (name);
266    
267     mt = find (name);
268    
269     if (mt)
270     mt->reset ();
271     else
272     {
273     mt = new materialtype_t;
274     mt->next = materialt; materialt = mt;
275     }
276 root 1.5
277 root 1.15 mt->name = name;
278     mt->description = name;
279     }
280 root 1.2 break;
281    
282     case KW_description:
283     thawer.get (mt->description);
284     break;
285    
286     case KW_material:
287     thawer.get (mt->material);
288     break;
289    
290     case KW_saves:
291     {
292     const char *cp = thawer.get_str () - 1;
293    
294     for (int i = 0; i < NROFATTACKS; i++)
295     {
296     if (!cp)
297     {
298     mt->save[i] = 0;
299     continue;
300     }
301    
302     int value;
303     ++cp;
304     sscanf (cp, "%d", &value);
305     mt->save[i] = (sint8) value;
306     cp = strchr (cp, ',');
307     }
308     }
309     break;
310    
311     case KW_mods:
312     {
313     const char *cp = thawer.get_str () - 1;
314    
315     for (int i = 0; i < NROFATTACKS; i++)
316     {
317     if (!cp)
318     {
319     mt->save[i] = 0;
320     continue;
321     }
322    
323     ++cp;
324     int value;
325     sscanf (cp, "%d", &value);
326     mt->mod[i] = (sint8) value;
327     cp = strchr (cp, ',');
328     }
329     }
330     break;
331    
332     case KW_chance: thawer.get (mt->chance); break;
333     case KW_difficulty: // cf+ alias, not original cf
334     case KW_diff: thawer.get (mt->difficulty); break;
335     case KW_magic: thawer.get (mt->magic); break;
336     case KW_dam: // cf+ alias, not original cf
337     case KW_damage: thawer.get (mt->damage); break;
338     case KW_wc: thawer.get (mt->wc); break;
339     case KW_ac: thawer.get (mt->ac); break;
340     case KW_sp: thawer.get (mt->sp); break;
341     case KW_weight: thawer.get (mt->weight); break;
342     case KW_value: thawer.get (mt->value); break;
343     case KW_density: thawer.get (mt->density); break;
344    
345     case KW_EOF:
346 root 1.15 return;
347 root 1.2
348     default:
349 root 1.12 if (!thawer.parse_error ("materials file"))
350 root 1.15 return;
351 root 1.2 break;
352     }
353    
354     thawer.next ();
355     }
356     }
357