… | |
… | |
88 | |
88 | |
89 | /* Sanity check - some stuff changes this when player is exiting */ |
89 | /* Sanity check - some stuff changes this when player is exiting */ |
90 | if (ob->type != PLAYER || !enable_save || !ns) |
90 | if (ob->type != PLAYER || !enable_save || !ns) |
91 | return; |
91 | return; |
92 | |
92 | |
93 | INVOKE_PLAYER (SAVE, ob->contr); |
93 | char filename[MAX_BUF]; |
|
|
94 | |
|
|
95 | sprintf (filename, "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, &ob->name, &ob->name); |
|
|
96 | make_path_to_file (filename); |
|
|
97 | |
|
|
98 | INVOKE_PLAYER (SAVE, ob->contr, ARG_STRING (filename)); |
94 | |
99 | |
95 | object_freezer freezer; |
100 | object_freezer freezer; |
96 | |
101 | |
97 | int wiz = ob->flag [FLAG_WIZ]; |
102 | int wiz = ob->flag [FLAG_WIZ]; |
98 | |
103 | |
99 | /* Eneq(@csd.uu.se): If we have an open container hide it. */ |
104 | /* Eneq(@csd.uu.se): If we have an open container hide it. */ |
100 | container = ob->container; |
105 | container = ob->container; |
101 | ob->container = 0; |
106 | ob->container = 0; |
102 | |
107 | |
103 | fprintf (freezer, "password %s\n", password); |
108 | #define PL_OUT(k) freezer.put (KW_ ## k, k) |
|
|
109 | #define PL_OUT2(k,v) freezer.put (KW_ ## k, v) |
104 | |
110 | |
105 | if (own_title[0] != '\0') |
111 | PL_OUT (password); |
106 | fprintf (freezer, "title %s\n", own_title); |
112 | PL_OUT2 (title, own_title); |
|
|
113 | PL_OUT (explore); |
|
|
114 | PL_OUT (gen_hp); |
|
|
115 | PL_OUT (gen_sp); |
|
|
116 | PL_OUT (gen_grace); |
|
|
117 | PL_OUT (listening); |
|
|
118 | PL_OUT (shoottype); |
|
|
119 | PL_OUT (bowtype); |
|
|
120 | PL_OUT (petmode); |
|
|
121 | PL_OUT (peaceful); |
|
|
122 | PL_OUT (digestion); |
|
|
123 | PL_OUT2 (pickup, mode); |
|
|
124 | PL_OUT (outputs_sync); |
|
|
125 | PL_OUT (outputs_count); |
107 | |
126 | |
108 | fprintf (freezer, "explore %d\n", explore); |
|
|
109 | fprintf (freezer, "gen_hp %d\n", gen_hp); |
|
|
110 | fprintf (freezer, "gen_sp %d\n", gen_sp); |
|
|
111 | fprintf (freezer, "gen_grace %d\n", gen_grace); |
|
|
112 | fprintf (freezer, "listening %d\n", listening); |
|
|
113 | fprintf (freezer, "shoottype %d\n", shoottype); |
|
|
114 | fprintf (freezer, "bowtype %d\n", bowtype); |
|
|
115 | fprintf (freezer, "petmode %d\n", petmode); |
|
|
116 | fprintf (freezer, "peaceful %d\n", peaceful); |
|
|
117 | fprintf (freezer, "digestion %d\n", digestion); |
|
|
118 | fprintf (freezer, "pickup %d\n", mode); |
|
|
119 | fprintf (freezer, "outputs_sync %d\n", outputs_sync); |
|
|
120 | fprintf (freezer, "outputs_count %d\n", outputs_count); |
|
|
121 | /* Match the enumerations but in string form */ |
|
|
122 | fprintf (freezer, "usekeys %s\n", usekeys == key_inventory ? "key_inventory" : (usekeys == keyrings ? "keyrings" : "containers")); |
127 | freezer.put (KW_usekeys, usekeys == key_inventory ? "key_inventory" : (usekeys == keyrings ? "keyrings" : "containers")); |
123 | /* Match the enumerations but in string form */ |
128 | freezer.put (KW_unapply, unapply == unapply_nochoice ? "unapply_nochoice" : (unapply == unapply_never ? "unapply_never" : "unapply_always")); |
124 | fprintf (freezer, "unapply %s\n", unapply == unapply_nochoice ? "unapply_nochoice" : |
|
|
125 | (unapply == unapply_never ? "unapply_never" : "unapply_always")); |
|
|
126 | |
129 | |
127 | if (ob->map) |
130 | if (ob->map) PL_OUT2 (map, ob->map->path); |
128 | fprintf (freezer, "map %s\n", &ob->map->path); |
|
|
129 | |
131 | |
130 | fprintf (freezer, "savebed_map %s\n", savebed_map); |
132 | PL_OUT (savebed_map); |
131 | fprintf (freezer, "bed_x %d\nbed_y %d\n", bed_x, bed_y); |
133 | PL_OUT (bed_x); |
132 | fprintf (freezer, "weapon_sp %f\n", weapon_sp); |
134 | PL_OUT (bed_y); |
133 | fprintf (freezer, "Str %d\n", orig_stats.Str); |
135 | PL_OUT (weapon_sp); |
134 | fprintf (freezer, "Dex %d\n", orig_stats.Dex); |
136 | PL_OUT2 (Str, orig_stats.Str); |
135 | fprintf (freezer, "Con %d\n", orig_stats.Con); |
137 | PL_OUT2 (Dex, orig_stats.Dex); |
136 | fprintf (freezer, "Int %d\n", orig_stats.Int); |
138 | PL_OUT2 (Con, orig_stats.Con); |
137 | fprintf (freezer, "Pow %d\n", orig_stats.Pow); |
139 | PL_OUT2 (Int, orig_stats.Int); |
138 | fprintf (freezer, "Wis %d\n", orig_stats.Wis); |
140 | PL_OUT2 (Pow, orig_stats.Pow); |
139 | fprintf (freezer, "Cha %d\n", orig_stats.Cha); |
141 | PL_OUT2 (Wis, orig_stats.Wis); |
|
|
142 | PL_OUT2 (Cha, orig_stats.Cha); |
140 | |
143 | |
141 | fprintf (freezer, "lev_array %d\n", ob->level > 10 ? 10 : ob->level); |
144 | PL_OUT2 (lev_array, min (ob->level, 10)); |
142 | |
145 | |
143 | for (int i = 1; i <= last_level && i <= 10; i++) |
146 | for (int i = 1; i <= last_level && i <= 10; i++) |
144 | { |
147 | { |
145 | fprintf (freezer, "%d\n", levhp[i]); |
148 | fprintf (freezer, "%d\n", levhp[i]); |
146 | fprintf (freezer, "%d\n", levsp[i]); |
149 | fprintf (freezer, "%d\n", levsp[i]); |
147 | fprintf (freezer, "%d\n", levgrace[i]); |
150 | fprintf (freezer, "%d\n", levgrace[i]); |
148 | } |
151 | } |
149 | |
152 | |
150 | freezer.put (ob->contr); |
153 | freezer.put (ob->contr); |
151 | |
154 | freezer.put (KW_endplst); |
152 | fprintf (freezer, "endplst\n"); |
|
|
153 | |
155 | |
154 | SET_FLAG (ob, FLAG_NO_FIX_PLAYER); |
156 | SET_FLAG (ob, FLAG_NO_FIX_PLAYER); |
155 | CLEAR_FLAG (ob, FLAG_WIZ); |
157 | CLEAR_FLAG (ob, FLAG_WIZ); |
156 | save_object (freezer, ob, 1); /* don't check and don't remove */ |
158 | save_object (freezer, ob, 1); /* don't check and don't remove */ |
157 | |
159 | |
158 | char filename[MAX_BUF]; |
|
|
159 | |
|
|
160 | sprintf (filename, "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, &ob->name, &ob->name); |
|
|
161 | make_path_to_file (filename); |
|
|
162 | freezer.save (filename); |
160 | freezer.save (filename); |
163 | |
161 | |
164 | CLEAR_FLAG (ob, FLAG_NO_FIX_PLAYER); |
162 | CLEAR_FLAG (ob, FLAG_NO_FIX_PLAYER); |
165 | |
163 | |
166 | /* Eneq(@csd.uu.se): Reveal the container if we have one. */ |
164 | /* Eneq(@csd.uu.se): Reveal the container if we have one. */ |
167 | ob->container = container; |
165 | ob->container = container; |
168 | |
166 | |
169 | ob->flag [FLAG_WIZ] = wiz; |
167 | ob->flag [FLAG_WIZ] = wiz; |
170 | |
168 | |
171 | enable_save = !final; |
169 | enable_save = !final; |
|
|
170 | |
|
|
171 | INVOKE_PLAYER (SAVE_DONE, ob->contr, ARG_STRING (filename)); |
172 | } |
172 | } |
173 | |
173 | |
174 | player * |
174 | player * |
175 | player::load (const char *path) |
175 | player::load (const char *path) |
176 | { |
176 | { |
… | |
… | |
188 | char buf[MAX_BUF], bufall[MAX_BUF]; |
188 | char buf[MAX_BUF], bufall[MAX_BUF]; |
189 | |
189 | |
190 | pl->set_object (object::create ()); |
190 | pl->set_object (object::create ()); |
191 | pl->last_save_time = time (0); |
191 | pl->last_save_time = time (0); |
192 | |
192 | |
193 | assign (pl->savebed_map, first_map_path); |
193 | pl->savebed_map = first_map_path; |
194 | |
194 | |
195 | /* Loop through the file, loading the rest of the values */ |
195 | /* Loop through the file, loading the rest of the values */ |
196 | while (fgets (bufall, MAX_BUF, thawer)) |
196 | for (;;) |
197 | { |
197 | { |
198 | int value; |
198 | keyword kw = thawer.get_kv (); |
199 | sscanf (bufall, "%s %d\n", buf, &value); |
|
|
200 | |
199 | |
201 | if (!strcmp (buf, "endplst")) |
200 | switch (kw) |
202 | break; |
|
|
203 | else if (!strcmp (buf, "oid")) |
|
|
204 | thawer.get (pl, value); |
|
|
205 | else if (!strcmp (buf, "password")) |
|
|
206 | sscanf (bufall, "password %[^\n]", pl->password); |
|
|
207 | else if (!strcmp (buf, "title")) |
|
|
208 | sscanf (bufall, "title %[^\n]", pl->own_title); |
|
|
209 | else if (!strcmp (buf, "explore")) |
|
|
210 | pl->explore = value; |
|
|
211 | else if (!strcmp (buf, "gen_hp")) |
|
|
212 | pl->gen_hp = value; |
|
|
213 | else if (!strcmp (buf, "shoottype")) |
|
|
214 | pl->shoottype = (rangetype) value; |
|
|
215 | else if (!strcmp (buf, "bowtype")) |
|
|
216 | pl->bowtype = (bowtype_t) value; |
|
|
217 | else if (!strcmp (buf, "petmode")) |
|
|
218 | pl->petmode = (petmode_t) value; |
|
|
219 | else if (!strcmp (buf, "gen_sp")) |
|
|
220 | pl->gen_sp = value; |
|
|
221 | else if (!strcmp (buf, "gen_grace")) |
|
|
222 | pl->gen_grace = value; |
|
|
223 | else if (!strcmp (buf, "listening")) |
|
|
224 | pl->listening = value; |
|
|
225 | else if (!strcmp (buf, "peaceful")) |
|
|
226 | pl->peaceful = value; |
|
|
227 | else if (!strcmp (buf, "digestion")) |
|
|
228 | pl->digestion = value; |
|
|
229 | else if (!strcmp (buf, "pickup")) |
|
|
230 | pl->mode = value; |
|
|
231 | else if (!strcmp (buf, "outputs_sync")) |
|
|
232 | pl->outputs_sync = value; |
|
|
233 | else if (!strcmp (buf, "outputs_count")) |
|
|
234 | pl->outputs_count = value; |
|
|
235 | else if (!strcmp (buf, "map")) |
|
|
236 | sscanf (bufall, "map %s", pl->maplevel); |
|
|
237 | else if (!strcmp (buf, "savebed_map")) |
|
|
238 | sscanf (bufall, "savebed_map %s", pl->savebed_map); |
|
|
239 | else if (!strcmp (buf, "bed_x")) |
|
|
240 | pl->bed_x = value; |
|
|
241 | else if (!strcmp (buf, "bed_y")) |
|
|
242 | pl->bed_y = value; |
|
|
243 | else if (!strcmp (buf, "weapon_sp")) |
|
|
244 | sscanf (buf, "weapon_sp %f", &pl->weapon_sp); |
|
|
245 | else if (!strcmp (buf, "Str")) |
|
|
246 | pl->orig_stats.Str = value; |
|
|
247 | else if (!strcmp (buf, "Dex")) |
|
|
248 | pl->orig_stats.Dex = value; |
|
|
249 | else if (!strcmp (buf, "Con")) |
|
|
250 | pl->orig_stats.Con = value; |
|
|
251 | else if (!strcmp (buf, "Int")) |
|
|
252 | pl->orig_stats.Int = value; |
|
|
253 | else if (!strcmp (buf, "Pow")) |
|
|
254 | pl->orig_stats.Pow = value; |
|
|
255 | else if (!strcmp (buf, "Wis")) |
|
|
256 | pl->orig_stats.Wis = value; |
|
|
257 | else if (!strcmp (buf, "Cha")) |
|
|
258 | pl->orig_stats.Cha = value; |
|
|
259 | else if (!strcmp (buf, "usekeys")) |
|
|
260 | { |
201 | { |
261 | if (!strcmp (bufall + 8, "key_inventory\n")) |
202 | case KW_EOF: |
|
|
203 | LOG (llevError, "%s: error while reading player header\n", path); |
|
|
204 | return 0; |
|
|
205 | |
|
|
206 | case KW_ERROR: |
|
|
207 | LOG (llevError, "%s: error while reading player header, skipping (%s,%s)\n", path, thawer.last_keyword, thawer.last_value); |
|
|
208 | break; |
|
|
209 | |
|
|
210 | case KW_endplst: |
|
|
211 | goto done; |
|
|
212 | |
|
|
213 | case KW_oid: thawer.get (pl, thawer.get_sint32 ()); break; |
|
|
214 | case KW_password: assign (pl->password , thawer.get_str ()); break; |
|
|
215 | case KW_title: assign (pl->own_title, thawer.get_str ()); break; |
|
|
216 | case KW_shoottype: pl->shoottype = (rangetype) thawer.get_sint32 (); break; |
|
|
217 | case KW_bowtype: pl->bowtype = (bowtype_t) thawer.get_sint32 (); break; |
|
|
218 | case KW_petmode: pl->petmode = (petmode_t) thawer.get_sint32 (); break; |
|
|
219 | case KW_explore: thawer.get (pl->explore); break; |
|
|
220 | case KW_listening: thawer.get (pl->listening); break; |
|
|
221 | case KW_peaceful: thawer.get (pl->peaceful); break; |
|
|
222 | case KW_digestion: thawer.get (pl->digestion); break; |
|
|
223 | case KW_pickup: thawer.get (pl->mode); break; |
|
|
224 | case KW_outputs_sync: thawer.get (pl->outputs_sync); break; |
|
|
225 | case KW_outputs_count: thawer.get (pl->outputs_count); break; |
|
|
226 | case KW_map: thawer.get (pl->maplevel); break; |
|
|
227 | case KW_savebed_map: thawer.get (pl->savebed_map); break; |
|
|
228 | case KW_bed_x: thawer.get (pl->bed_x); break; |
|
|
229 | case KW_bed_y: thawer.get (pl->bed_y); break; |
|
|
230 | case KW_weapon_sp: thawer.get (pl->weapon_sp); break; |
|
|
231 | case KW_Str: thawer.get (pl->orig_stats.Str); break; |
|
|
232 | case KW_Dex: thawer.get (pl->orig_stats.Dex); break; |
|
|
233 | case KW_Con: thawer.get (pl->orig_stats.Con); break; |
|
|
234 | case KW_Int: thawer.get (pl->orig_stats.Int); break; |
|
|
235 | case KW_Pow: thawer.get (pl->orig_stats.Pow); break; |
|
|
236 | case KW_Wis: thawer.get (pl->orig_stats.Wis); break; |
|
|
237 | case KW_Cha: thawer.get (pl->orig_stats.Cha); break; |
|
|
238 | case KW_gen_hp: thawer.get (pl->gen_hp); break; |
|
|
239 | case KW_gen_sp: thawer.get (pl->gen_sp); break; |
|
|
240 | case KW_gen_grace: thawer.get (pl->gen_grace); break; |
|
|
241 | |
|
|
242 | case KW_usekeys: |
|
|
243 | if (!strcmp (thawer.get_str (), "key_inventory")) |
262 | pl->usekeys = key_inventory; |
244 | pl->usekeys = key_inventory; |
263 | else if (!strcmp (bufall + 8, "keyrings\n")) |
245 | else if (!strcmp (thawer.get_str (), "keyrings")) |
264 | pl->usekeys = keyrings; |
246 | pl->usekeys = keyrings; |
265 | else if (!strcmp (bufall + 8, "containers\n")) |
247 | else if (!strcmp (thawer.get_str (), "containers")) |
266 | pl->usekeys = containers; |
248 | pl->usekeys = containers; |
267 | else |
249 | else |
268 | LOG (llevDebug, "load_player: got unknown usekeys type: %s\n", bufall + 8); |
250 | LOG (llevDebug, "load_player: got unknown usekeys type: %s\n", thawer.get_str ()); |
|
|
251 | break; |
|
|
252 | |
|
|
253 | case KW_unapply: |
|
|
254 | if (!strcmp (thawer.get_str (), "unapply_nochoice")) |
|
|
255 | pl->unapply = unapply_nochoice; |
|
|
256 | else if (!strcmp (thawer.get_str (), "unapply_never")) |
|
|
257 | pl->unapply = unapply_never; |
|
|
258 | else if (!strcmp (thawer.get_str (), "unapply_always")) |
|
|
259 | pl->unapply = unapply_always; |
|
|
260 | else |
|
|
261 | LOG (llevDebug, "load_player: got unknown unapply type: %s\n", thawer.get_str ()); |
|
|
262 | break; |
|
|
263 | |
|
|
264 | case KW_lev_array: |
|
|
265 | { |
|
|
266 | int count = thawer.get_sint32 (); |
|
|
267 | |
|
|
268 | for (int i = 1; i <= count; i++) |
|
|
269 | { |
|
|
270 | char line[128]; |
|
|
271 | |
|
|
272 | fgets (line, 128, thawer); pl->levhp [i] = atoi (line); |
|
|
273 | fgets (line, 128, thawer); pl->levsp [i] = atoi (line); |
|
|
274 | fgets (line, 128, thawer); pl->levgrace[i] = atoi (line); |
|
|
275 | } |
|
|
276 | } |
|
|
277 | break; |
|
|
278 | |
|
|
279 | default: |
|
|
280 | LOG (llevError, "%s: skipping unknown key in player header: %s\n", path, keyword_str [kw]); |
|
|
281 | break; |
269 | } |
282 | } |
270 | else if (!strcmp (buf, "unapply")) |
|
|
271 | { |
|
|
272 | if (!strcmp (bufall + 8, "unapply_nochoice\n")) |
|
|
273 | pl->unapply = unapply_nochoice; |
|
|
274 | else if (!strcmp (bufall + 8, "unapply_never\n")) |
|
|
275 | pl->unapply = unapply_never; |
|
|
276 | else if (!strcmp (bufall + 8, "unapply_always\n")) |
|
|
277 | pl->unapply = unapply_always; |
|
|
278 | else |
|
|
279 | LOG (llevDebug, "load_player: got unknown unapply type: %s\n", bufall + 8); |
|
|
280 | } |
|
|
281 | else if (!strcmp (buf, "lev_array")) |
|
|
282 | { |
|
|
283 | for (int i = 1; i <= value; i++) |
|
|
284 | { |
|
|
285 | char line[128]; |
|
|
286 | |
|
|
287 | fgets (line, 128, thawer); |
|
|
288 | pl->levhp[i] = atoi (line); |
|
|
289 | fgets (line, 128, thawer); |
|
|
290 | pl->levsp[i] = atoi (line); |
|
|
291 | fgets (line, 128, thawer); |
|
|
292 | pl->levgrace[i] = atoi (line); |
|
|
293 | } |
|
|
294 | /* spell_array code removed - don't know when that was last used. |
|
|
295 | * Even the load code below will someday be replaced by spells being |
|
|
296 | * objects. |
|
|
297 | */ |
|
|
298 | } |
|
|
299 | else |
|
|
300 | LOG (llevDebug, "unparseable line in player file %s: %s\n", path, bufall); |
|
|
301 | } |
283 | } |
302 | |
284 | |
|
|
285 | done: |
303 | /* this loads the standard objects values. */ |
286 | /* this loads the standard objects values. */ |
304 | load_object (thawer, pl->ob, 0); |
287 | load_object (thawer, pl->ob, 0); |
305 | |
288 | |
306 | pl->last_save_tick = pticks; |
289 | pl->last_save_tick = pticks; |
307 | |
290 | |