ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/player.C
Revision: 1.24
Committed: Mon Apr 30 04:25:29 2007 UTC (17 years ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.23: +0 -30 lines
Log Message:
This is the first rough cut of the skill use system (use the STABLE tag).

Details will likely change, and combat skills do not work very well, but
it works quite well.

Players no longer have a shoottype or range slots, instead, each player
has these members:

   combat_skill/combat_ob  the currently selected skill (and weapon)
                           for direct attacks.
   ranged_skill/ranged_ob  the currently selected ranged skill (and
                           bow/spell/item)
   golem                   the currently-controlled golem, if any.

File Contents

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