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

# User Rev Content
1 elmex 1.1 /*
2 root 1.14 * 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 elmex 1.1
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 root 1.4 int
34     atnr_is_dragon_enabled (int attacknr)
35     {
36 elmex 1.1 if (attacknr == ATNR_MAGIC || attacknr == ATNR_FIRE ||
37 root 1.4 attacknr == ATNR_ELECTRICITY || attacknr == ATNR_COLD || attacknr == ATNR_ACID || attacknr == ATNR_POISON)
38 elmex 1.1 return 1;
39 root 1.10
40 elmex 1.1 return 0;
41     }
42    
43     /*
44     * returns true if the adressed object 'ob' is a player
45     * of the dragon race.
46     */
47 root 1.4 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 elmex 1.1 return 1;
52 root 1.18
53 elmex 1.1 return 0;
54     }
55 root 1.14
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 root 1.19 if (ob->map)
71     maplevel = ob->map->path;
72    
73 root 1.14 #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 root 1.18 freezer.put (KW_usekeys, usekeys == key_inventory ? "key_inventory" : (usekeys == keyrings ? "keyrings" : "containers"));
91 root 1.14 freezer.put (KW_unapply, unapply == unapply_nochoice ? "unapply_nochoice" : (unapply == unapply_never ? "unapply_never" : "unapply_always"));
92    
93 root 1.17 PL_OUT2 (map, maplevel);
94 root 1.14 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 root 1.15 PL_OUT2 (lev_array, 10);
107 root 1.14
108 root 1.15 for (int i = 1; i <= 10; i++)
109 root 1.14 {
110 root 1.15 fprintf (freezer, "%d\n", levhp [i]);
111     fprintf (freezer, "%d\n", levsp [i]);
112 root 1.14 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 root 1.21 ob->write (freezer);
121 root 1.14
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 root 1.21 player::load_pl (object_thawer &f)
147 root 1.14 {
148 root 1.21 int maxerrs = 20;
149 root 1.18
150 root 1.14 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 root 1.21 switch (f.kw)
158 root 1.14 {
159     case KW_EOF:
160 root 1.21 LOG (llevError, "%s: unexpected EOF while reading player header\n", f.name);
161 root 1.18 goto failure;
162    
163     default:
164 root 1.21 LOG (llevError, "%s: skipping unknown key in player header: %s\n", f.name, f.kw_str);
165 root 1.18 if (!--maxerrs) goto failure;
166     break;
167 root 1.14
168     case KW_ERROR:
169 root 1.21 LOG (llevError, "%s: parse error while reading player header, skipping (%s,%s).\n", f.name, f.kw_str, f.value);
170 root 1.18 if (!--maxerrs) goto failure;
171 root 1.14 break;
172    
173     case KW_endplst:
174 root 1.21 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 root 1.14
183 root 1.21 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 root 1.14
212     case KW_usekeys:
213 root 1.21 if (!strcmp (f.get_str (), "key_inventory"))
214 root 1.14 pl->usekeys = key_inventory;
215 root 1.21 else if (!strcmp (f.get_str (), "keyrings"))
216 root 1.14 pl->usekeys = keyrings;
217 root 1.21 else if (!strcmp (f.get_str (), "containers"))
218 root 1.14 pl->usekeys = containers;
219     else
220 root 1.21 LOG (llevDebug, "load_player: got unknown usekeys type: %s\n", f.get_str ());
221 root 1.14 break;
222    
223     case KW_unapply:
224 root 1.21 if (!strcmp (f.get_str (), "unapply_nochoice"))
225 root 1.14 pl->unapply = unapply_nochoice;
226 root 1.21 else if (!strcmp (f.get_str (), "unapply_never"))
227 root 1.14 pl->unapply = unapply_never;
228 root 1.21 else if (!strcmp (f.get_str (), "unapply_always"))
229 root 1.14 pl->unapply = unapply_always;
230     else
231 root 1.21 LOG (llevDebug, "load_player: got unknown unapply type: %s\n", f.get_str ());
232 root 1.14 break;
233    
234     case KW_lev_array:
235     {
236 root 1.21 int count = f.get_sint32 ();
237 root 1.14
238     for (int i = 1; i <= count; i++)
239     {
240 root 1.16 char line [32];
241 root 1.14
242 root 1.21 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 root 1.14 }
246     }
247     break;
248     }
249    
250 root 1.21 f.next ();
251 root 1.14 }
252    
253 root 1.18 failure:
254 root 1.21 LOG (llevError, "%s: too many or too grave errors, aborting player load.\n", f.name);
255 root 1.18
256 root 1.22 if (pl->ob)
257     pl->ob->destroy ();
258    
259 root 1.18 pl->destroy ();
260    
261     return 0;
262 root 1.14 }
263    
264     player *
265     player::load_pl (const char *path)
266     {
267 root 1.21 object_thawer f (path);
268 root 1.14
269 root 1.21 if (!f)
270 root 1.14 return 0;
271    
272 root 1.21 f.next ();
273    
274     return load_pl (f);
275 root 1.14 }
276