ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/material.C
Revision: 1.3
Committed: Thu Nov 5 15:43:21 2009 UTC (14 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_90
Changes since 1.2: +4 -0 lines
Log Message:
mark gpl sections, common/

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 root 1.3 //+GPL
29    
30 root 1.1 /* convert materialname to materialtype_t */
31    
32     materialtype_t *
33     name_to_material (const shstr_cmp name)
34     {
35     for (materialtype_t *mt = materialt; mt; mt = mt->next)
36     if (name == mt->name)
37     return mt;
38    
39     return 0;
40     }
41    
42     /* when doing transmutation of objects, we have to recheck the resistances,
43     * as some that did not apply previously, may apply now.
44     */
45     void
46     transmute_materialname (object *op, const object *change)
47     {
48     materialtype_t *mt;
49     int j;
50    
51     if (!op->materialname)
52     return;
53    
54     if (op->materialname != change->materialname)
55     return;
56    
57     if (!op->is_armor ())
58     return;
59    
60     mt = name_to_material (op->materialname);
61     if (!mt)
62     {
63     LOG (llevError, "archetype '%s>%s' uses nonexistent material '%s'\n", &op->arch->archname, &op->name, &op->materialname);
64     return;
65     }
66    
67     for (j = 0; j < NROFATTACKS; j++)
68     if (op->resist[j] == 0 && change->resist[j] != 0)
69     {
70     op->resist[j] += mt->mod[j];
71     if (op->resist[j] > 100)
72     op->resist[j] = 100;
73     if (op->resist[j] < -100)
74     op->resist[j] = -100;
75     }
76     }
77    
78     /* set the materialname and type for an item */
79     void
80     set_materialname (object *op, int difficulty, materialtype_t *nmt)
81     {
82     materialtype_t *mt, *lmt;
83    
84     if (!op->materialname)
85     return;
86    
87     if (nmt)
88     lmt = nmt;
89     else
90     {
91     lmt = 0;
92    
93     for (mt = materialt; mt; mt = mt->next)
94     if (op->materials & mt->material && rndm (1, 100) <= mt->chance &&
95     difficulty >= mt->difficulty && (op->magic >= mt->magic || mt->magic == 0))
96     {
97     lmt = mt;
98     if (!(op->is_weapon () || op->is_armor ()))
99     break;
100     }
101     }
102    
103     if (lmt)
104     {
105     if (op->stats.dam && op->is_weapon ())
106     {
107     op->stats.dam += lmt->damage;
108     if (op->stats.dam < 1)
109     op->stats.dam = 1;
110     }
111    
112     if (op->stats.sp && op->type == BOW)
113     op->stats.sp += lmt->sp;
114     if (op->stats.wc && op->is_weapon ())
115     op->stats.wc += lmt->wc;
116     if (op->is_armor ())
117     {
118     if (op->stats.ac)
119     op->stats.ac += lmt->ac;
120    
121     for (int j = 0; j < NROFATTACKS; j++)
122     if (op->resist[j] != 0)
123     {
124     op->resist[j] += lmt->mod[j];
125     if (op->resist[j] > 100)
126     op->resist[j] = 100;
127     if (op->resist[j] < -100)
128     op->resist[j] = -100;
129     }
130     }
131    
132     op->materialname = lmt->name;
133     /* dont make it unstackable if it doesn't need to be */
134     if (op->is_weapon () || op->is_armor ())
135     {
136     op->weight = (op->weight * lmt->weight) / 100;
137     op->value = (op->value * lmt->value) / 100;
138     }
139     }
140     }
141    
142 root 1.2 //TODO: make this a constructor
143     static materialtype_t *
144     get_empty_mat (void)
145     {
146     materialtype_t *mt;
147     int i;
148    
149     mt = new materialtype_t;
150    
151     mt->name = shstr_unknown;
152     mt->description = 0;
153    
154     for (i = 0; i < NROFATTACKS; i++)
155     {
156     mt->save[i] = 0;
157     mt->mod[i] = 0;
158     }
159    
160     mt->chance = 0;
161     mt->difficulty = 0;
162     mt->magic = 0;
163     mt->damage = 0;
164     mt->wc = 0;
165     mt->ac = 0;
166     mt->sp = 0;
167     mt->weight = 100;
168     mt->value = 100;
169     mt->density = 1;
170     mt->next = 0;
171    
172     return mt;
173     }
174    
175 root 1.3 //-GPL
176    
177 root 1.2 void
178     load_materials (void)
179     {
180     char filename[MAX_BUF];
181    
182     sprintf (filename, "%s/materials", settings.datadir);
183     LOG (llevDebug, "Reading material type data from %s...\n", filename);
184    
185     //TODO: somehow free old materials, or update them in-place
186     materialt = 0;
187    
188     object_thawer thawer (filename);
189    
190     if (!thawer)
191     {
192     LOG (llevError, "Cannot open %s for reading\n", filename);
193     goto done;
194     }
195    
196     while (thawer.kw != KW_name)
197     {
198     thawer.next ();
199    
200     if (thawer.kw == KW_EOF)
201     goto done;
202     }
203    
204     materialtype_t *mt;
205    
206     for (;;)
207     {
208     switch (thawer.kw)
209     {
210     case KW_name:
211     mt = get_empty_mat ();
212     mt->next = materialt;
213     materialt = mt;
214    
215     thawer.get (mt->name);
216     mt->description = mt->name;
217     break;
218    
219     case KW_description:
220     thawer.get (mt->description);
221     break;
222    
223     case KW_material:
224     thawer.get (mt->material);
225     break;
226    
227     case KW_saves:
228     {
229     const char *cp = thawer.get_str () - 1;
230    
231     for (int i = 0; i < NROFATTACKS; i++)
232     {
233     if (!cp)
234     {
235     mt->save[i] = 0;
236     continue;
237     }
238    
239     int value;
240     ++cp;
241     sscanf (cp, "%d", &value);
242     mt->save[i] = (sint8) value;
243     cp = strchr (cp, ',');
244     }
245     }
246     break;
247    
248     case KW_mods:
249     {
250     const char *cp = thawer.get_str () - 1;
251    
252     for (int i = 0; i < NROFATTACKS; i++)
253     {
254     if (!cp)
255     {
256     mt->save[i] = 0;
257     continue;
258     }
259    
260     ++cp;
261     int value;
262     sscanf (cp, "%d", &value);
263     mt->mod[i] = (sint8) value;
264     cp = strchr (cp, ',');
265     }
266     }
267     break;
268    
269     case KW_chance: thawer.get (mt->chance); break;
270     case KW_difficulty: // cf+ alias, not original cf
271     case KW_diff: thawer.get (mt->difficulty); break;
272     case KW_magic: thawer.get (mt->magic); break;
273     case KW_dam: // cf+ alias, not original cf
274     case KW_damage: thawer.get (mt->damage); break;
275     case KW_wc: thawer.get (mt->wc); break;
276     case KW_ac: thawer.get (mt->ac); break;
277     case KW_sp: thawer.get (mt->sp); break;
278     case KW_weight: thawer.get (mt->weight); break;
279     case KW_value: thawer.get (mt->value); break;
280     case KW_density: thawer.get (mt->density); break;
281    
282     case KW_EOF:
283     goto done;
284    
285     default:
286     if (!thawer.parse_error ("materials file", "materials"))
287     goto done;
288     break;
289     }
290    
291     thawer.next ();
292     }
293    
294     done:
295     if (!materialt)
296     materialt = get_empty_mat ();
297    
298     LOG (llevDebug, "Done.\n");
299     }
300