1 | /* |
1 | /* |
2 | CrossFire, A Multiplayer game for X-windows |
2 | CrossFire, A Multiplayer game for X-windows |
3 | |
3 | |
|
|
4 | Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team |
4 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
5 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
5 | Copyright (C) 1992 Frank Tore Johansen |
6 | Copyright (C) 1992 Frank Tore Johansen |
6 | |
7 | |
7 | This program is free software; you can redistribute it and/or modify |
8 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
9 | it under the terms of the GNU General Public License as published by |
… | |
… | |
29 | |
30 | |
30 | extern void sub_weight (object *, signed long); |
31 | extern void sub_weight (object *, signed long); |
31 | extern void add_weight (object *, signed long); |
32 | extern void add_weight (object *, signed long); |
32 | extern long pticks; |
33 | extern long pticks; |
33 | |
34 | |
34 | /* If flag is non zero, it means that we want to try and save everyone, but |
|
|
35 | * keep the game running. Thus, we don't want to free any information. |
|
|
36 | */ |
|
|
37 | void |
|
|
38 | emergency_save (int flag) |
|
|
39 | { |
|
|
40 | trying_emergency_save = 1; |
|
|
41 | |
|
|
42 | LOG (llevError, "Emergency save: "); |
|
|
43 | for_all_players (pl) |
|
|
44 | { |
|
|
45 | if (!pl->ob) |
|
|
46 | { |
|
|
47 | LOG (llevError, "No name, ignoring this.\n"); |
|
|
48 | continue; |
|
|
49 | } |
|
|
50 | |
|
|
51 | LOG (llevError, "%s ", &pl->ob->name); |
|
|
52 | new_draw_info (NDI_UNIQUE, 0, pl->ob, "Emergency save..."); |
|
|
53 | |
|
|
54 | /* If we are not exiting the game (ie, this is sort of a backup save), then |
|
|
55 | * don't change the location back to the village. Note that there are other |
|
|
56 | * options to have backup saves be done at the starting village |
|
|
57 | */ |
|
|
58 | if (!flag) |
|
|
59 | { |
|
|
60 | strcpy (pl->maplevel, first_map_path); |
|
|
61 | |
|
|
62 | pl->ob->map = 0; |
|
|
63 | pl->ob->x = -1; |
|
|
64 | pl->ob->y = -1; |
|
|
65 | } |
|
|
66 | |
|
|
67 | pl->save (1); |
|
|
68 | } |
|
|
69 | |
|
|
70 | LOG (llevError, "\n"); |
|
|
71 | } |
|
|
72 | |
|
|
73 | /* Delete character with name. if new is set, also delete the new |
35 | /* Delete character with name. if new is set, also delete the new |
74 | * style directory, otherwise, just delete the old style playfile |
36 | * style directory, otherwise, just delete the old style playfile |
75 | * (needed for transition) |
37 | * (needed for transition) |
76 | */ |
38 | */ |
77 | void |
39 | void |
78 | delete_character (const char *name, int newchar) |
40 | delete_character (const char *name) |
79 | { |
41 | { |
80 | char buf[MAX_BUF]; |
42 | char buf[MAX_BUF]; |
81 | |
43 | |
82 | sprintf (buf, "%s/%s/%s.pl", settings.localdir, settings.playerdir, name); |
44 | sprintf (buf, "%s/%s/%s", settings.localdir, settings.playerdir, name); |
83 | |
|
|
84 | if (unlink (buf) == -1) |
|
|
85 | LOG (llevDebug, "Cannot delete character file %s: %s\n", buf, strerror (errno)); |
|
|
86 | |
|
|
87 | if (newchar) |
|
|
88 | { |
|
|
89 | sprintf (buf, "%s/%s/%s", settings.localdir, settings.playerdir, name); |
|
|
90 | /* this effectively does an rm -rf on the directory */ |
45 | /* this effectively does an rm -rf on the directory */ |
91 | remove_directory (buf); |
46 | remove_directory (buf); |
92 | } |
|
|
93 | } |
47 | } |
94 | |
48 | |
95 | int |
49 | int |
96 | create_savedir_if_needed (char *savedir) |
50 | create_savedir_if_needed (char *savedir) |
97 | { |
51 | { |
… | |
… | |
127 | |
81 | |
128 | /* Sanity check - some stuff changes this when player is exiting */ |
82 | /* Sanity check - some stuff changes this when player is exiting */ |
129 | if (ob->type != PLAYER || !enable_save || !ns) |
83 | if (ob->type != PLAYER || !enable_save || !ns) |
130 | return; |
84 | return; |
131 | |
85 | |
132 | INVOKE_PLAYER (SAVE, ob->contr); |
86 | char filename[MAX_BUF]; |
|
|
87 | |
|
|
88 | sprintf (filename, "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, &ob->name, &ob->name); |
|
|
89 | make_path_to_file (filename); |
|
|
90 | |
|
|
91 | INVOKE_PLAYER (SAVE, ob->contr, ARG_STRING (filename)); |
133 | |
92 | |
134 | object_freezer freezer; |
93 | object_freezer freezer; |
135 | |
94 | |
136 | int wiz = ob->flag [FLAG_WIZ]; |
95 | int wiz = ob->flag [FLAG_WIZ]; |
137 | |
96 | |
138 | /* Eneq(@csd.uu.se): If we have an open container hide it. */ |
97 | /* Eneq(@csd.uu.se): If we have an open container hide it. */ |
139 | container = ob->container; |
98 | container = ob->container; |
140 | ob->container = 0; |
99 | ob->container = 0; |
141 | |
100 | |
142 | fprintf (freezer, "password %s\n", password); |
101 | #define PL_OUT(k) freezer.put (KW_ ## k, k) |
|
|
102 | #define PL_OUT2(k,v) freezer.put (KW_ ## k, v) |
143 | |
103 | |
144 | if (own_title[0] != '\0') |
104 | PL_OUT (password); |
145 | fprintf (freezer, "title %s\n", own_title); |
105 | PL_OUT2 (title, own_title); |
|
|
106 | PL_OUT (explore); |
|
|
107 | PL_OUT (gen_hp); |
|
|
108 | PL_OUT (gen_sp); |
|
|
109 | PL_OUT (gen_grace); |
|
|
110 | PL_OUT (listening); |
|
|
111 | PL_OUT (shoottype); |
|
|
112 | PL_OUT (bowtype); |
|
|
113 | PL_OUT (petmode); |
|
|
114 | PL_OUT (peaceful); |
|
|
115 | PL_OUT (digestion); |
|
|
116 | PL_OUT2 (pickup, mode); |
|
|
117 | PL_OUT (outputs_sync); |
|
|
118 | PL_OUT (outputs_count); |
146 | |
119 | |
147 | fprintf (freezer, "explore %d\n", explore); |
|
|
148 | fprintf (freezer, "gen_hp %d\n", gen_hp); |
|
|
149 | fprintf (freezer, "gen_sp %d\n", gen_sp); |
|
|
150 | fprintf (freezer, "gen_grace %d\n", gen_grace); |
|
|
151 | fprintf (freezer, "listening %d\n", listening); |
|
|
152 | fprintf (freezer, "shoottype %d\n", shoottype); |
|
|
153 | fprintf (freezer, "bowtype %d\n", bowtype); |
|
|
154 | fprintf (freezer, "petmode %d\n", petmode); |
|
|
155 | fprintf (freezer, "peaceful %d\n", peaceful); |
|
|
156 | fprintf (freezer, "digestion %d\n", digestion); |
|
|
157 | fprintf (freezer, "pickup %d\n", mode); |
|
|
158 | fprintf (freezer, "outputs_sync %d\n", outputs_sync); |
|
|
159 | fprintf (freezer, "outputs_count %d\n", outputs_count); |
|
|
160 | /* Match the enumerations but in string form */ |
|
|
161 | fprintf (freezer, "usekeys %s\n", usekeys == key_inventory ? "key_inventory" : (usekeys == keyrings ? "keyrings" : "containers")); |
120 | freezer.put (KW_usekeys, usekeys == key_inventory ? "key_inventory" : (usekeys == keyrings ? "keyrings" : "containers")); |
162 | /* Match the enumerations but in string form */ |
121 | freezer.put (KW_unapply, unapply == unapply_nochoice ? "unapply_nochoice" : (unapply == unapply_never ? "unapply_never" : "unapply_always")); |
163 | fprintf (freezer, "unapply %s\n", unapply == unapply_nochoice ? "unapply_nochoice" : |
|
|
164 | (unapply == unapply_never ? "unapply_never" : "unapply_always")); |
|
|
165 | |
122 | |
166 | if (ob->map) |
123 | if (ob->map) PL_OUT2 (map, ob->map->path); |
167 | fprintf (freezer, "map %s\n", ob->map->path); |
|
|
168 | else |
|
|
169 | fprintf (freezer, "map %s\n", settings.emergency_mapname); |
|
|
170 | |
124 | |
171 | fprintf (freezer, "savebed_map %s\n", savebed_map); |
125 | PL_OUT (savebed_map); |
172 | fprintf (freezer, "bed_x %d\nbed_y %d\n", bed_x, bed_y); |
126 | PL_OUT (bed_x); |
173 | fprintf (freezer, "weapon_sp %f\n", weapon_sp); |
127 | PL_OUT (bed_y); |
174 | fprintf (freezer, "Str %d\n", orig_stats.Str); |
128 | PL_OUT (weapon_sp); |
175 | fprintf (freezer, "Dex %d\n", orig_stats.Dex); |
129 | PL_OUT2 (Str, orig_stats.Str); |
176 | fprintf (freezer, "Con %d\n", orig_stats.Con); |
130 | PL_OUT2 (Dex, orig_stats.Dex); |
177 | fprintf (freezer, "Int %d\n", orig_stats.Int); |
131 | PL_OUT2 (Con, orig_stats.Con); |
178 | fprintf (freezer, "Pow %d\n", orig_stats.Pow); |
132 | PL_OUT2 (Int, orig_stats.Int); |
179 | fprintf (freezer, "Wis %d\n", orig_stats.Wis); |
133 | PL_OUT2 (Pow, orig_stats.Pow); |
180 | fprintf (freezer, "Cha %d\n", orig_stats.Cha); |
134 | PL_OUT2 (Wis, orig_stats.Wis); |
|
|
135 | PL_OUT2 (Cha, orig_stats.Cha); |
181 | |
136 | |
182 | fprintf (freezer, "lev_array %d\n", ob->level > 10 ? 10 : ob->level); |
137 | PL_OUT2 (lev_array, min (ob->level, 10)); |
183 | |
138 | |
184 | for (int i = 1; i <= last_level && i <= 10; i++) |
139 | for (int i = 1; i <= last_level && i <= 10; i++) |
185 | { |
140 | { |
186 | fprintf (freezer, "%d\n", levhp[i]); |
141 | fprintf (freezer, "%d\n", levhp[i]); |
187 | fprintf (freezer, "%d\n", levsp[i]); |
142 | fprintf (freezer, "%d\n", levsp[i]); |
188 | fprintf (freezer, "%d\n", levgrace[i]); |
143 | fprintf (freezer, "%d\n", levgrace[i]); |
189 | } |
144 | } |
190 | |
145 | |
191 | freezer.put (ob->contr); |
146 | freezer.put (ob->contr); |
192 | |
147 | freezer.put (KW_endplst); |
193 | fprintf (freezer, "endplst\n"); |
|
|
194 | |
148 | |
195 | SET_FLAG (ob, FLAG_NO_FIX_PLAYER); |
149 | SET_FLAG (ob, FLAG_NO_FIX_PLAYER); |
196 | CLEAR_FLAG (ob, FLAG_WIZ); |
150 | CLEAR_FLAG (ob, FLAG_WIZ); |
197 | save_object (freezer, ob, 1); /* don't check and don't remove */ |
151 | save_object (freezer, ob, 1); /* don't check and don't remove */ |
198 | |
152 | |
199 | char filename[MAX_BUF]; |
|
|
200 | |
|
|
201 | sprintf (filename, "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, &ob->name, &ob->name); |
|
|
202 | make_path_to_file (filename); |
|
|
203 | freezer.save (filename); |
153 | freezer.save (filename); |
204 | |
154 | |
205 | CLEAR_FLAG (ob, FLAG_NO_FIX_PLAYER); |
155 | CLEAR_FLAG (ob, FLAG_NO_FIX_PLAYER); |
206 | |
156 | |
207 | /* Eneq(@csd.uu.se): Reveal the container if we have one. */ |
157 | /* Eneq(@csd.uu.se): Reveal the container if we have one. */ |
208 | ob->container = container; |
158 | ob->container = container; |
209 | |
159 | |
210 | ob->flag [FLAG_WIZ] = wiz; |
160 | ob->flag [FLAG_WIZ] = wiz; |
211 | |
161 | |
212 | enable_save = !final; |
162 | enable_save = !final; |
|
|
163 | |
|
|
164 | INVOKE_PLAYER (SAVE_DONE, ob->contr, ARG_STRING (filename)); |
213 | } |
165 | } |
214 | |
166 | |
215 | player * |
167 | player * |
216 | player::load (const char *path) |
168 | player::load (const char *path) |
217 | { |
169 | { |
… | |
… | |
229 | char buf[MAX_BUF], bufall[MAX_BUF]; |
181 | char buf[MAX_BUF], bufall[MAX_BUF]; |
230 | |
182 | |
231 | pl->set_object (object::create ()); |
183 | pl->set_object (object::create ()); |
232 | pl->last_save_time = time (0); |
184 | pl->last_save_time = time (0); |
233 | |
185 | |
234 | assign (pl->savebed_map, first_map_path); |
186 | pl->savebed_map = first_map_path; |
235 | |
187 | |
236 | /* Loop through the file, loading the rest of the values */ |
188 | /* Loop through the file, loading the rest of the values */ |
237 | while (fgets (bufall, MAX_BUF, thawer)) |
189 | for (;;) |
238 | { |
190 | { |
239 | int value; |
191 | keyword kw = thawer.get_kv (); |
240 | sscanf (bufall, "%s %d\n", buf, &value); |
|
|
241 | |
192 | |
242 | if (!strcmp (buf, "endplst")) |
193 | switch (kw) |
243 | break; |
|
|
244 | else if (!strcmp (buf, "oid")) |
|
|
245 | thawer.get (pl, value); |
|
|
246 | else if (!strcmp (buf, "password")) |
|
|
247 | sscanf (bufall, "password %[^\n]", pl->password); |
|
|
248 | else if (!strcmp (buf, "title")) |
|
|
249 | sscanf (bufall, "title %[^\n]", pl->own_title); |
|
|
250 | else if (!strcmp (buf, "explore")) |
|
|
251 | pl->explore = value; |
|
|
252 | else if (!strcmp (buf, "gen_hp")) |
|
|
253 | pl->gen_hp = value; |
|
|
254 | else if (!strcmp (buf, "shoottype")) |
|
|
255 | pl->shoottype = (rangetype) value; |
|
|
256 | else if (!strcmp (buf, "bowtype")) |
|
|
257 | pl->bowtype = (bowtype_t) value; |
|
|
258 | else if (!strcmp (buf, "petmode")) |
|
|
259 | pl->petmode = (petmode_t) value; |
|
|
260 | else if (!strcmp (buf, "gen_sp")) |
|
|
261 | pl->gen_sp = value; |
|
|
262 | else if (!strcmp (buf, "gen_grace")) |
|
|
263 | pl->gen_grace = value; |
|
|
264 | else if (!strcmp (buf, "listening")) |
|
|
265 | pl->listening = value; |
|
|
266 | else if (!strcmp (buf, "peaceful")) |
|
|
267 | pl->peaceful = value; |
|
|
268 | else if (!strcmp (buf, "digestion")) |
|
|
269 | pl->digestion = value; |
|
|
270 | else if (!strcmp (buf, "pickup")) |
|
|
271 | pl->mode = value; |
|
|
272 | else if (!strcmp (buf, "outputs_sync")) |
|
|
273 | pl->outputs_sync = value; |
|
|
274 | else if (!strcmp (buf, "outputs_count")) |
|
|
275 | pl->outputs_count = value; |
|
|
276 | else if (!strcmp (buf, "map")) |
|
|
277 | sscanf (bufall, "map %s", pl->maplevel); |
|
|
278 | else if (!strcmp (buf, "savebed_map")) |
|
|
279 | sscanf (bufall, "savebed_map %s", pl->savebed_map); |
|
|
280 | else if (!strcmp (buf, "bed_x")) |
|
|
281 | pl->bed_x = value; |
|
|
282 | else if (!strcmp (buf, "bed_y")) |
|
|
283 | pl->bed_y = value; |
|
|
284 | else if (!strcmp (buf, "weapon_sp")) |
|
|
285 | sscanf (buf, "weapon_sp %f", &pl->weapon_sp); |
|
|
286 | else if (!strcmp (buf, "Str")) |
|
|
287 | pl->orig_stats.Str = value; |
|
|
288 | else if (!strcmp (buf, "Dex")) |
|
|
289 | pl->orig_stats.Dex = value; |
|
|
290 | else if (!strcmp (buf, "Con")) |
|
|
291 | pl->orig_stats.Con = value; |
|
|
292 | else if (!strcmp (buf, "Int")) |
|
|
293 | pl->orig_stats.Int = value; |
|
|
294 | else if (!strcmp (buf, "Pow")) |
|
|
295 | pl->orig_stats.Pow = value; |
|
|
296 | else if (!strcmp (buf, "Wis")) |
|
|
297 | pl->orig_stats.Wis = value; |
|
|
298 | else if (!strcmp (buf, "Cha")) |
|
|
299 | pl->orig_stats.Cha = value; |
|
|
300 | else if (!strcmp (buf, "usekeys")) |
|
|
301 | { |
194 | { |
302 | if (!strcmp (bufall + 8, "key_inventory\n")) |
195 | case KW_EOF: |
|
|
196 | LOG (llevError, "%s: error while reading player header\n", path); |
|
|
197 | return 0; |
|
|
198 | |
|
|
199 | case KW_ERROR: |
|
|
200 | LOG (llevError, "%s: error while reading player header, skipping (%s,%s)\n", path, thawer.last_keyword, thawer.last_value); |
|
|
201 | break; |
|
|
202 | |
|
|
203 | case KW_endplst: |
|
|
204 | goto done; |
|
|
205 | |
|
|
206 | case KW_oid: thawer.get (pl, thawer.get_sint32 ()); break; |
|
|
207 | case KW_password: assign (pl->password , thawer.get_str ()); break; |
|
|
208 | case KW_title: assign (pl->own_title, thawer.get_str ()); break; |
|
|
209 | case KW_shoottype: pl->shoottype = (rangetype) thawer.get_sint32 (); break; |
|
|
210 | case KW_bowtype: pl->bowtype = (bowtype_t) thawer.get_sint32 (); break; |
|
|
211 | case KW_petmode: pl->petmode = (petmode_t) thawer.get_sint32 (); break; |
|
|
212 | case KW_explore: thawer.get (pl->explore); break; |
|
|
213 | case KW_listening: thawer.get (pl->listening); break; |
|
|
214 | case KW_peaceful: thawer.get (pl->peaceful); break; |
|
|
215 | case KW_digestion: thawer.get (pl->digestion); break; |
|
|
216 | case KW_pickup: thawer.get (pl->mode); break; |
|
|
217 | case KW_outputs_sync: thawer.get (pl->outputs_sync); break; |
|
|
218 | case KW_outputs_count: thawer.get (pl->outputs_count); break; |
|
|
219 | case KW_map: thawer.get (pl->maplevel); break; |
|
|
220 | case KW_savebed_map: thawer.get (pl->savebed_map); break; |
|
|
221 | case KW_bed_x: thawer.get (pl->bed_x); break; |
|
|
222 | case KW_bed_y: thawer.get (pl->bed_y); break; |
|
|
223 | case KW_weapon_sp: thawer.get (pl->weapon_sp); break; |
|
|
224 | case KW_Str: thawer.get (pl->orig_stats.Str); break; |
|
|
225 | case KW_Dex: thawer.get (pl->orig_stats.Dex); break; |
|
|
226 | case KW_Con: thawer.get (pl->orig_stats.Con); break; |
|
|
227 | case KW_Int: thawer.get (pl->orig_stats.Int); break; |
|
|
228 | case KW_Pow: thawer.get (pl->orig_stats.Pow); break; |
|
|
229 | case KW_Wis: thawer.get (pl->orig_stats.Wis); break; |
|
|
230 | case KW_Cha: thawer.get (pl->orig_stats.Cha); break; |
|
|
231 | case KW_gen_hp: thawer.get (pl->gen_hp); break; |
|
|
232 | case KW_gen_sp: thawer.get (pl->gen_sp); break; |
|
|
233 | case KW_gen_grace: thawer.get (pl->gen_grace); break; |
|
|
234 | |
|
|
235 | case KW_usekeys: |
|
|
236 | if (!strcmp (thawer.get_str (), "key_inventory")) |
303 | pl->usekeys = key_inventory; |
237 | pl->usekeys = key_inventory; |
304 | else if (!strcmp (bufall + 8, "keyrings\n")) |
238 | else if (!strcmp (thawer.get_str (), "keyrings")) |
305 | pl->usekeys = keyrings; |
239 | pl->usekeys = keyrings; |
306 | else if (!strcmp (bufall + 8, "containers\n")) |
240 | else if (!strcmp (thawer.get_str (), "containers")) |
307 | pl->usekeys = containers; |
241 | pl->usekeys = containers; |
308 | else |
242 | else |
309 | LOG (llevDebug, "load_player: got unknown usekeys type: %s\n", bufall + 8); |
243 | LOG (llevDebug, "load_player: got unknown usekeys type: %s\n", thawer.get_str ()); |
|
|
244 | break; |
|
|
245 | |
|
|
246 | case KW_unapply: |
|
|
247 | if (!strcmp (thawer.get_str (), "unapply_nochoice")) |
|
|
248 | pl->unapply = unapply_nochoice; |
|
|
249 | else if (!strcmp (thawer.get_str (), "unapply_never")) |
|
|
250 | pl->unapply = unapply_never; |
|
|
251 | else if (!strcmp (thawer.get_str (), "unapply_always")) |
|
|
252 | pl->unapply = unapply_always; |
|
|
253 | else |
|
|
254 | LOG (llevDebug, "load_player: got unknown unapply type: %s\n", thawer.get_str ()); |
|
|
255 | break; |
|
|
256 | |
|
|
257 | case KW_lev_array: |
|
|
258 | { |
|
|
259 | int count = thawer.get_sint32 (); |
|
|
260 | |
|
|
261 | for (int i = 1; i <= count; i++) |
|
|
262 | { |
|
|
263 | char line[128]; |
|
|
264 | |
|
|
265 | fgets (line, 128, thawer); pl->levhp [i] = atoi (line); |
|
|
266 | fgets (line, 128, thawer); pl->levsp [i] = atoi (line); |
|
|
267 | fgets (line, 128, thawer); pl->levgrace[i] = atoi (line); |
|
|
268 | } |
|
|
269 | } |
|
|
270 | break; |
|
|
271 | |
|
|
272 | default: |
|
|
273 | LOG (llevError, "%s: skipping unknown key in player header: %s\n", path, keyword_str [kw]); |
|
|
274 | break; |
310 | } |
275 | } |
311 | else if (!strcmp (buf, "unapply")) |
|
|
312 | { |
|
|
313 | if (!strcmp (bufall + 8, "unapply_nochoice\n")) |
|
|
314 | pl->unapply = unapply_nochoice; |
|
|
315 | else if (!strcmp (bufall + 8, "unapply_never\n")) |
|
|
316 | pl->unapply = unapply_never; |
|
|
317 | else if (!strcmp (bufall + 8, "unapply_always\n")) |
|
|
318 | pl->unapply = unapply_always; |
|
|
319 | else |
|
|
320 | LOG (llevDebug, "load_player: got unknown unapply type: %s\n", bufall + 8); |
|
|
321 | } |
|
|
322 | else if (!strcmp (buf, "lev_array")) |
|
|
323 | { |
|
|
324 | for (int i = 1; i <= value; i++) |
|
|
325 | { |
|
|
326 | char line[128]; |
|
|
327 | |
|
|
328 | fgets (line, 128, thawer); |
|
|
329 | pl->levhp[i] = atoi (line); |
|
|
330 | fgets (line, 128, thawer); |
|
|
331 | pl->levsp[i] = atoi (line); |
|
|
332 | fgets (line, 128, thawer); |
|
|
333 | pl->levgrace[i] = atoi (line); |
|
|
334 | } |
|
|
335 | /* spell_array code removed - don't know when that was last used. |
|
|
336 | * Even the load code below will someday be replaced by spells being |
|
|
337 | * objects. |
|
|
338 | */ |
|
|
339 | } |
|
|
340 | else |
|
|
341 | LOG (llevDebug, "unparseable line in player file %s: %s\n", path, bufall); |
|
|
342 | } |
276 | } |
343 | |
277 | |
|
|
278 | done: |
344 | /* this loads the standard objects values. */ |
279 | /* this loads the standard objects values. */ |
345 | load_object (thawer, pl->ob, 0); |
280 | load_object (thawer, pl->ob, 0); |
346 | |
281 | |
347 | /* If the map where the person was last saved does not exist, |
|
|
348 | * restart them on their home-savebed. This is good for when |
|
|
349 | * maps change between versions |
|
|
350 | * First, we check for partial path, then check to see if the full |
|
|
351 | * path (for unique player maps) |
|
|
352 | */ |
|
|
353 | if (!has_been_loaded (pl->maplevel) |
|
|
354 | && check_path (pl->maplevel, 1) == -1 |
|
|
355 | && check_path (pl->maplevel, 0) == -1) |
|
|
356 | { |
|
|
357 | strcpy (pl->maplevel, pl->savebed_map); |
|
|
358 | pl->ob->x = pl->bed_x, pl->ob->y = pl->bed_y; |
|
|
359 | } |
|
|
360 | |
|
|
361 | pl->last_save_tick = pticks; |
282 | pl->last_save_tick = pticks; |
362 | |
283 | |
363 | INVOKE_PLAYER (LOAD, pl, ARG_STRING (path)); |
284 | INVOKE_PLAYER (LOAD, pl, ARG_STRING (path)); |
364 | |
285 | |
365 | return pl; |
286 | return pl; |