ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/material.C
Revision: 1.2
Committed: Wed Nov 4 00:08:44 2009 UTC (14 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.1: +157 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 /*
2     * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3     *
4     * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5     * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6     * Copyright (©) 1992,2007 Frank Tore Johansen
7     *
8     * Deliantra is free software: you can redistribute it and/or modify it under
9     * the terms of the Affero GNU General Public License as published by the
10     * Free Software Foundation, either version 3 of the License, or (at your
11     * option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the Affero GNU General Public License
19     * and the GNU General Public License along with this program. If not, see
20     * <http://www.gnu.org/licenses/>.
21     *
22     * The authors can be reached via e-mail to <support@deliantra.net>
23     */
24    
25     #include <global.h>
26     #include <material.h>
27    
28     /* convert materialname to materialtype_t */
29    
30     materialtype_t *
31     name_to_material (const shstr_cmp name)
32     {
33     for (materialtype_t *mt = materialt; mt; mt = mt->next)
34     if (name == mt->name)
35     return mt;
36    
37     return 0;
38     }
39    
40     /* when doing transmutation of objects, we have to recheck the resistances,
41     * as some that did not apply previously, may apply now.
42     */
43     void
44     transmute_materialname (object *op, const object *change)
45     {
46     materialtype_t *mt;
47     int j;
48    
49     if (!op->materialname)
50     return;
51    
52     if (op->materialname != change->materialname)
53     return;
54    
55     if (!op->is_armor ())
56     return;
57    
58     mt = name_to_material (op->materialname);
59     if (!mt)
60     {
61     LOG (llevError, "archetype '%s>%s' uses nonexistent material '%s'\n", &op->arch->archname, &op->name, &op->materialname);
62     return;
63     }
64    
65     for (j = 0; j < NROFATTACKS; j++)
66     if (op->resist[j] == 0 && change->resist[j] != 0)
67     {
68     op->resist[j] += mt->mod[j];
69     if (op->resist[j] > 100)
70     op->resist[j] = 100;
71     if (op->resist[j] < -100)
72     op->resist[j] = -100;
73     }
74     }
75    
76     /* set the materialname and type for an item */
77     void
78     set_materialname (object *op, int difficulty, materialtype_t *nmt)
79     {
80     materialtype_t *mt, *lmt;
81    
82     if (!op->materialname)
83     return;
84    
85     if (nmt)
86     lmt = nmt;
87     else
88     {
89     lmt = 0;
90    
91     for (mt = materialt; mt; mt = mt->next)
92     if (op->materials & mt->material && rndm (1, 100) <= mt->chance &&
93     difficulty >= mt->difficulty && (op->magic >= mt->magic || mt->magic == 0))
94     {
95     lmt = mt;
96     if (!(op->is_weapon () || op->is_armor ()))
97     break;
98     }
99     }
100    
101     if (lmt)
102     {
103     if (op->stats.dam && op->is_weapon ())
104     {
105     op->stats.dam += lmt->damage;
106     if (op->stats.dam < 1)
107     op->stats.dam = 1;
108     }
109    
110     if (op->stats.sp && op->type == BOW)
111     op->stats.sp += lmt->sp;
112     if (op->stats.wc && op->is_weapon ())
113     op->stats.wc += lmt->wc;
114     if (op->is_armor ())
115     {
116     if (op->stats.ac)
117     op->stats.ac += lmt->ac;
118    
119     for (int j = 0; j < NROFATTACKS; j++)
120     if (op->resist[j] != 0)
121     {
122     op->resist[j] += lmt->mod[j];
123     if (op->resist[j] > 100)
124     op->resist[j] = 100;
125     if (op->resist[j] < -100)
126     op->resist[j] = -100;
127     }
128     }
129    
130     op->materialname = lmt->name;
131     /* dont make it unstackable if it doesn't need to be */
132     if (op->is_weapon () || op->is_armor ())
133     {
134     op->weight = (op->weight * lmt->weight) / 100;
135     op->value = (op->value * lmt->value) / 100;
136     }
137     }
138     }
139    
140 root 1.2 //TODO: make this a constructor
141     static materialtype_t *
142     get_empty_mat (void)
143     {
144     materialtype_t *mt;
145     int i;
146    
147     mt = new materialtype_t;
148    
149     mt->name = shstr_unknown;
150     mt->description = 0;
151    
152     for (i = 0; i < NROFATTACKS; i++)
153     {
154     mt->save[i] = 0;
155     mt->mod[i] = 0;
156     }
157    
158     mt->chance = 0;
159     mt->difficulty = 0;
160     mt->magic = 0;
161     mt->damage = 0;
162     mt->wc = 0;
163     mt->ac = 0;
164     mt->sp = 0;
165     mt->weight = 100;
166     mt->value = 100;
167     mt->density = 1;
168     mt->next = 0;
169    
170     return mt;
171     }
172    
173     void
174     load_materials (void)
175     {
176     char filename[MAX_BUF];
177    
178     sprintf (filename, "%s/materials", settings.datadir);
179     LOG (llevDebug, "Reading material type data from %s...\n", filename);
180    
181     //TODO: somehow free old materials, or update them in-place
182     materialt = 0;
183    
184     object_thawer thawer (filename);
185    
186     if (!thawer)
187     {
188     LOG (llevError, "Cannot open %s for reading\n", filename);
189     goto done;
190     }
191    
192     while (thawer.kw != KW_name)
193     {
194     thawer.next ();
195    
196     if (thawer.kw == KW_EOF)
197     goto done;
198     }
199    
200     materialtype_t *mt;
201    
202     for (;;)
203     {
204     switch (thawer.kw)
205     {
206     case KW_name:
207     mt = get_empty_mat ();
208     mt->next = materialt;
209     materialt = mt;
210    
211     thawer.get (mt->name);
212     mt->description = mt->name;
213     break;
214    
215     case KW_description:
216     thawer.get (mt->description);
217     break;
218    
219     case KW_material:
220     thawer.get (mt->material);
221     break;
222    
223     case KW_saves:
224     {
225     const char *cp = thawer.get_str () - 1;
226    
227     for (int i = 0; i < NROFATTACKS; i++)
228     {
229     if (!cp)
230     {
231     mt->save[i] = 0;
232     continue;
233     }
234    
235     int value;
236     ++cp;
237     sscanf (cp, "%d", &value);
238     mt->save[i] = (sint8) value;
239     cp = strchr (cp, ',');
240     }
241     }
242     break;
243    
244     case KW_mods:
245     {
246     const char *cp = thawer.get_str () - 1;
247    
248     for (int i = 0; i < NROFATTACKS; i++)
249     {
250     if (!cp)
251     {
252     mt->save[i] = 0;
253     continue;
254     }
255    
256     ++cp;
257     int value;
258     sscanf (cp, "%d", &value);
259     mt->mod[i] = (sint8) value;
260     cp = strchr (cp, ',');
261     }
262     }
263     break;
264    
265     case KW_chance: thawer.get (mt->chance); break;
266     case KW_difficulty: // cf+ alias, not original cf
267     case KW_diff: thawer.get (mt->difficulty); break;
268     case KW_magic: thawer.get (mt->magic); break;
269     case KW_dam: // cf+ alias, not original cf
270     case KW_damage: thawer.get (mt->damage); break;
271     case KW_wc: thawer.get (mt->wc); break;
272     case KW_ac: thawer.get (mt->ac); break;
273     case KW_sp: thawer.get (mt->sp); break;
274     case KW_weight: thawer.get (mt->weight); break;
275     case KW_value: thawer.get (mt->value); break;
276     case KW_density: thawer.get (mt->density); break;
277    
278     case KW_EOF:
279     goto done;
280    
281     default:
282     if (!thawer.parse_error ("materials file", "materials"))
283     goto done;
284     break;
285     }
286    
287     thawer.next ();
288     }
289    
290     done:
291     if (!materialt)
292     materialt = get_empty_mat ();
293    
294     LOG (llevDebug, "Done.\n");
295     }
296