ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/player.C
Revision: 1.33
Committed: Sun Jul 1 05:00:17 2007 UTC (16 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.32: +11 -12 lines
Log Message:
- upgrade crossfire trt to the GPL version 3 (hopefully correctly).
- add a single file covered by the GNU Affero General Public License
  (which is not yet released, so I used the current draft, which is
  legally a bit wavy, but its likely better than nothing as it expresses
  direct intent by the authors, and we can upgrade as soon as it has been
  released).
  * this should ensure availability of source code for the server at least
    and hopefully also archetypes and maps even when modified versions
    are not being distributed, in accordance of section 13 of the agplv3.

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.33 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 root 1.30 *
4     * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5     * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6     * Copyright (©) 1992,2007 Frank Tore Johansen
7     *
8 root 1.33 * Crossfire TRT is free software: you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation, either version 3 of the License, or
11     * (at your option) any later version.
12 root 1.30 *
13 root 1.33 * 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 root 1.30 *
18 root 1.33 * You should have received a copy of the GNU General Public License
19     * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 root 1.30 *
21     * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 root 1.14 */
23 elmex 1.1
24     #include <global.h>
25     #include <funcpoint.h>
26    
27     /* Determine if the attacktype represented by the
28     * specified attack-number is enabled for dragon players.
29     * A dragon player (quetzal) can gain resistances for
30     * all enabled attacktypes.
31     */
32 root 1.4 int
33     atnr_is_dragon_enabled (int attacknr)
34     {
35 elmex 1.1 if (attacknr == ATNR_MAGIC || attacknr == ATNR_FIRE ||
36 root 1.4 attacknr == ATNR_ELECTRICITY || attacknr == ATNR_COLD || attacknr == ATNR_ACID || attacknr == ATNR_POISON)
37 elmex 1.1 return 1;
38 root 1.10
39 elmex 1.1 return 0;
40     }
41    
42     /*
43     * returns true if the adressed object 'ob' is a player
44     * of the dragon race.
45     */
46 root 1.4 int
47     is_dragon_pl (const object *op)
48     {
49 root 1.25 if (op
50     && op->type == PLAYER
51     && op->arch
52 root 1.31 && op->arch->race
53     && !strcmp (op->arch->race, "dragon"))
54 elmex 1.1 return 1;
55 root 1.18
56 elmex 1.1 return 0;
57     }
58 root 1.14
59     /*
60     * If final is set, it a clean/final save, not a backup, ie dont remove objects from inventory
61     */
62     bool
63     player::save_pl (object_freezer &freezer)
64     {
65     INVOKE_PLAYER (SAVE, ob->contr);
66    
67     int wiz = ob->flag [FLAG_WIZ];
68    
69     /* Eneq(@csd.uu.se): If we have an open container hide it. */
70     object *container = ob->container;
71     ob->container = 0;
72    
73 root 1.19 if (ob->map)
74     maplevel = ob->map->path;
75    
76 root 1.14 #define PL_OUT(k) freezer.put (KW_ ## k, k)
77     #define PL_OUT2(k,v) freezer.put (KW_ ## k, v)
78    
79     PL_OUT (password);
80     PL_OUT2 (title, own_title);
81 root 1.32 PL_OUT (gender);
82 root 1.14 PL_OUT (gen_hp);
83     PL_OUT (gen_sp);
84     PL_OUT (gen_grace);
85     PL_OUT (listening);
86     PL_OUT (bowtype);
87     PL_OUT (petmode);
88     PL_OUT (peaceful);
89     PL_OUT (digestion);
90     PL_OUT2 (pickup, mode);
91     PL_OUT (outputs_sync);
92     PL_OUT (outputs_count);
93    
94 root 1.18 freezer.put (KW_usekeys, usekeys == key_inventory ? "key_inventory" : (usekeys == keyrings ? "keyrings" : "containers"));
95 root 1.14 freezer.put (KW_unapply, unapply == unapply_nochoice ? "unapply_nochoice" : (unapply == unapply_never ? "unapply_never" : "unapply_always"));
96    
97 root 1.17 PL_OUT2 (map, maplevel);
98 root 1.14 PL_OUT (savebed_map);
99     PL_OUT (bed_x);
100     PL_OUT (bed_y);
101     PL_OUT (weapon_sp);
102 root 1.28 PL_OUT (weapon_sp_left);
103 root 1.14 PL_OUT2 (Str, orig_stats.Str);
104     PL_OUT2 (Dex, orig_stats.Dex);
105     PL_OUT2 (Con, orig_stats.Con);
106     PL_OUT2 (Int, orig_stats.Int);
107     PL_OUT2 (Pow, orig_stats.Pow);
108     PL_OUT2 (Wis, orig_stats.Wis);
109     PL_OUT2 (Cha, orig_stats.Cha);
110    
111 root 1.15 PL_OUT2 (lev_array, 10);
112 root 1.14
113 root 1.15 for (int i = 1; i <= 10; i++)
114 root 1.14 {
115 root 1.29 freezer.add (levhp [i]); freezer.add ('\n');
116     freezer.add (levsp [i]); freezer.add ('\n');
117     freezer.add (levgrace[i]); freezer.add ('\n');
118 root 1.14 }
119    
120     freezer.put (ob->contr);
121     freezer.put (KW_endplst);
122    
123     SET_FLAG (ob, FLAG_NO_FIX_PLAYER);
124     CLEAR_FLAG (ob, FLAG_WIZ);
125 root 1.21 ob->write (freezer);
126 root 1.14
127     CLEAR_FLAG (ob, FLAG_NO_FIX_PLAYER);
128    
129     /* Eneq(@csd.uu.se): Reveal the container if we have one. */
130     ob->container = container;
131    
132     ob->flag [FLAG_WIZ] = wiz;
133    
134     INVOKE_PLAYER (SAVE_DONE, ob->contr);
135    
136     return true;
137     }
138    
139     bool
140     player::save_pl (const char *path)
141     {
142     object_freezer freezer;
143    
144     if (!save_pl (freezer))
145     return false;
146    
147     return freezer.save (path);
148     }
149    
150     player *
151 root 1.21 player::load_pl (object_thawer &f)
152 root 1.14 {
153 root 1.21 int maxerrs = 20;
154 root 1.18
155 root 1.14 player *pl = new player;
156    
157     pl->savebed_map = first_map_path;
158    
159     /* Loop through the file, loading the rest of the values */
160     for (;;)
161     {
162 root 1.21 switch (f.kw)
163 root 1.14 {
164     case KW_EOF:
165 root 1.21 LOG (llevError, "%s: unexpected EOF while reading player header\n", f.name);
166 root 1.18 goto failure;
167    
168     default:
169 root 1.21 LOG (llevError, "%s: skipping unknown key in player header: %s\n", f.name, f.kw_str);
170 root 1.18 if (!--maxerrs) goto failure;
171     break;
172 root 1.14
173     case KW_ERROR:
174 root 1.21 LOG (llevError, "%s: parse error while reading player header, skipping (%s,%s).\n", f.name, f.kw_str, f.value);
175 root 1.18 if (!--maxerrs) goto failure;
176 root 1.14 break;
177    
178     case KW_endplst:
179 root 1.21 f.next ();
180    
181     if (object *op = pl->ob->read (f))
182     pl->set_object (op);
183     else
184     goto failure;
185    
186     INVOKE_PLAYER (LOAD, pl);
187 root 1.14
188 root 1.21 return pl;
189    
190     case KW_oid: f.get (pl, f.get_sint32 ()); break;
191     case KW_password: assign (pl->password , f.get_str ()); break;
192     case KW_title: assign (pl->own_title, f.get_str ()); break;
193     case KW_bowtype: pl->bowtype = (bowtype_t) f.get_sint32 (); break;
194     case KW_petmode: pl->petmode = (petmode_t) f.get_sint32 (); break;
195 root 1.32 case KW_gender: f.get (pl->gender); break;
196 root 1.21 case KW_listening: f.get (pl->listening); break;
197     case KW_peaceful: f.get (pl->peaceful); break;
198     case KW_digestion: f.get (pl->digestion); break;
199     case KW_pickup: f.get (pl->mode); break;
200     case KW_outputs_sync: f.get (pl->outputs_sync); break;
201     case KW_outputs_count: f.get (pl->outputs_count); break;
202     case KW_map: f.get (pl->maplevel); break;
203     case KW_savebed_map: f.get (pl->savebed_map); break;
204     case KW_bed_x: f.get (pl->bed_x); break;
205     case KW_bed_y: f.get (pl->bed_y); break;
206     case KW_weapon_sp: f.get (pl->weapon_sp); break;
207 root 1.28 case KW_weapon_sp_left:f.get (pl->weapon_sp_left); break;
208 root 1.21 case KW_Str: f.get (pl->orig_stats.Str); break;
209     case KW_Dex: f.get (pl->orig_stats.Dex); break;
210     case KW_Con: f.get (pl->orig_stats.Con); break;
211     case KW_Int: f.get (pl->orig_stats.Int); break;
212     case KW_Pow: f.get (pl->orig_stats.Pow); break;
213     case KW_Wis: f.get (pl->orig_stats.Wis); break;
214     case KW_Cha: f.get (pl->orig_stats.Cha); break;
215     case KW_gen_hp: f.get (pl->gen_hp); break;
216     case KW_gen_sp: f.get (pl->gen_sp); break;
217     case KW_gen_grace: f.get (pl->gen_grace); break;
218 root 1.14
219     case KW_usekeys:
220 root 1.21 if (!strcmp (f.get_str (), "key_inventory"))
221 root 1.14 pl->usekeys = key_inventory;
222 root 1.21 else if (!strcmp (f.get_str (), "keyrings"))
223 root 1.14 pl->usekeys = keyrings;
224 root 1.21 else if (!strcmp (f.get_str (), "containers"))
225 root 1.14 pl->usekeys = containers;
226     else
227 root 1.21 LOG (llevDebug, "load_player: got unknown usekeys type: %s\n", f.get_str ());
228 root 1.14 break;
229    
230     case KW_unapply:
231 root 1.21 if (!strcmp (f.get_str (), "unapply_nochoice"))
232 root 1.14 pl->unapply = unapply_nochoice;
233 root 1.21 else if (!strcmp (f.get_str (), "unapply_never"))
234 root 1.14 pl->unapply = unapply_never;
235 root 1.21 else if (!strcmp (f.get_str (), "unapply_always"))
236 root 1.14 pl->unapply = unapply_always;
237     else
238 root 1.21 LOG (llevDebug, "load_player: got unknown unapply type: %s\n", f.get_str ());
239 root 1.14 break;
240    
241     case KW_lev_array:
242     {
243 root 1.21 int count = f.get_sint32 ();
244 root 1.14
245     for (int i = 1; i <= count; i++)
246     {
247 root 1.16 char line [32];
248 root 1.14
249 root 1.21 fgets (line, 32, f); pl->levhp [i] = atoi (line);
250     fgets (line, 32, f); pl->levsp [i] = atoi (line);
251     fgets (line, 32, f); pl->levgrace[i] = atoi (line);
252 root 1.14 }
253     }
254     break;
255     }
256    
257 root 1.21 f.next ();
258 root 1.14 }
259    
260 root 1.18 failure:
261 root 1.21 LOG (llevError, "%s: too many or too grave errors, aborting player load.\n", f.name);
262 root 1.18
263 root 1.22 if (pl->ob)
264     pl->ob->destroy ();
265    
266 root 1.18 pl->destroy ();
267    
268     return 0;
269 root 1.14 }
270    
271     player *
272     player::load_pl (const char *path)
273     {
274 root 1.21 object_thawer f (path);
275 root 1.14
276 root 1.21 if (!f)
277 root 1.14 return 0;
278    
279 root 1.21 f.next ();
280    
281     return load_pl (f);
282 root 1.14 }
283