ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/resurrection.C
Revision: 1.11
Committed: Tue Dec 12 20:53:03 2006 UTC (17 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.10: +2 -2 lines
Log Message:
replace some function- by method-calls

File Contents

# User Rev Content
1 elmex 1.1 /*
2     CrossFire, A Multiplayer game for X-windows
3    
4     Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5     Copyright (C) 1992 Frank Tore Johansen
6    
7     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     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21 root 1.7 The authors can be reached via e-mail at <crossfire@schmorp.de>
22 elmex 1.1 */
23    
24     /* the contents of this file were create solely by peterm@soda.berkeley.edu
25     all of the above disclaimers apply. */
26    
27     #include <global.h>
28     #ifndef __CEXTRACT__
29 root 1.5 # include <sproto.h>
30 elmex 1.1 #endif
31     #include <spells.h>
32     #include <errno.h>
33     #ifdef sequent
34 root 1.5
35 elmex 1.1 /* stoopid sequent includes don't do this like they should */
36 root 1.5 extern char *sys_errlist[];
37 elmex 1.1 extern int sys_nerr;
38     #endif
39     extern char **classname;
40     extern object *objects;
41    
42    
43    
44     /* name of the person to resurrect and which spell was used
45     * to resurrect
46     */
47 root 1.5 static int
48     resurrect_player (object *op, char *playername, object *spell)
49 elmex 1.1 {
50 root 1.5 FILE *deadplayer, *liveplayer;
51    
52     char oldname[MAX_BUF];
53     char newname[MAX_BUF];
54     char path[MAX_BUF];
55     char buf[MAX_BUF];
56     char buf2[MAX_BUF];
57     const char *race = NULL;
58     sint64 exp;
59     int Con;
60    
61    
62     /* reincarnation, which changes the race */
63     if (spell->race)
64     {
65     treasurelist *tl = find_treasurelist (spell->race);
66     treasure *t;
67     int value;
68    
69     if (!tl)
70     {
71     LOG (llevError, "resurrect_player: race set to %s, but no treasurelist of that name!\n", &spell->race);
72     return 0;
73     }
74     value = RANDOM () % tl->total_chance;
75     for (t = tl->items; t; t = t->next)
76     {
77     value -= t->chance;
78     if (value < 0)
79     break;
80     }
81     if (!t)
82     {
83     LOG (llevError, "resurrect_player: got null treasure from treasurelist %s!\n", &spell->race);
84     return 0;
85     }
86     race = t->item->name;
87     }
88    
89     /* set up our paths/strings... */
90     sprintf (path, "%s/%s/%s/%s", settings.localdir, settings.playerdir, playername, playername);
91    
92     strcpy (newname, path);
93     strcat (newname, ".pl");
94    
95     strcpy (oldname, newname);
96     strcat (oldname, ".dead");
97 elmex 1.1
98 root 1.5 if (!(deadplayer = fopen (oldname, "r")))
99     {
100     new_draw_info_format (NDI_UNIQUE, 0, op, "The soul of %s cannot be reached.", playername);
101     return 0;
102     }
103    
104     if (!access (newname, 0))
105     {
106     new_draw_info_format (NDI_UNIQUE, 0, op, "The soul of %s has already been reborn!", playername);
107     fclose (deadplayer);
108     return 0;
109     }
110    
111     if (!(liveplayer = fopen (newname, "w")))
112     {
113     new_draw_info_format (NDI_UNIQUE, 0, op, "The soul of %s cannot be re-embodied at the moment.", playername);
114     LOG (llevError, "Cannot write player in resurrect_player!\n");
115     fclose (deadplayer);
116     return 0;
117     }
118    
119     while (!feof (deadplayer))
120     {
121     fgets (buf, 255, deadplayer);
122     sscanf (buf, "%s", buf2);
123     if (!(strcmp (buf2, "exp")))
124     {
125 root 1.10 sscanf (buf, "%s %" SCNd64, buf2, &exp);
126 root 1.5 if (spell->stats.exp)
127     {
128     exp -= exp / spell->stats.exp;
129 root 1.10 sprintf (buf, "exp %" PRId64 "\n", exp);
130 root 1.2 }
131     }
132 root 1.5 if (!(strcmp (buf2, "Con")))
133     {
134     sscanf (buf, "%s %d", buf2, &Con);
135     Con -= spell->stats.Con;
136     if (Con < 1)
137     Con = 1;
138     sprintf (buf, "Con %d\n", Con);
139     }
140     if (race && !strcmp (buf2, "race"))
141     {
142     sprintf (buf, "race %s\n", race);
143     }
144     fputs (buf, liveplayer);
145     }
146     fclose (liveplayer);
147     fclose (deadplayer);
148     unlink (oldname);
149     new_draw_info_format (NDI_UNIQUE, 0, op, "%s lives again!", playername);
150 elmex 1.1
151 root 1.5 return 1;
152 elmex 1.1 }
153    
154    
155     /* raise_dead by peterm and mehlhaff@soda.berkeley.edu
156     * op -- who is doing the resurrecting
157     * spell - spell object
158     * dir -- direction the spell is cast
159     * corpseobj - corpse to raise - can be null, in which case this function will find it
160     */
161 root 1.5 int
162     cast_raise_dead_spell (object *op, object *caster, object *spell, int dir, const char *arg)
163 elmex 1.1 {
164 root 1.5 object *temp, *newob;
165     char name_to_resurrect[MAX_BUF];
166     int leveldead = 25, mflags, clevel;
167     sint16 sx, sy;
168 root 1.8 maptile *m;
169 root 1.5
170     clevel = caster_level (caster, spell);
171    
172     if (spell->last_heal)
173     {
174     if (!arg)
175     {
176     new_draw_info_format (NDI_UNIQUE, 0, op, "Cast %s on who?", &spell->name);
177     return 0;
178 root 1.2 }
179 root 1.5 strcpy (name_to_resurrect, arg);
180     temp = NULL;
181     }
182     else
183     {
184     sx = op->x + freearr_x[dir];
185     sy = op->y + freearr_y[dir];
186     m = op->map;
187     mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
188     if (mflags & P_OUT_OF_MAP)
189 root 1.2 temp = NULL;
190 root 1.5 else
191     {
192     /* First we need to find a corpse, if any. */
193     /* If no object, temp will be set to NULL */
194     for (temp = get_map_ob (m, sx, sy); temp != NULL; temp = temp->above)
195     /* If it is corpse, this must be what we want to raise */
196     if (temp->type == CORPSE)
197     break;
198     }
199    
200     if (temp == NULL)
201     {
202     new_draw_info (NDI_UNIQUE, 0, op, "You need a body for this spell.");
203     return 0;
204     }
205     strcpy (name_to_resurrect, temp->name);
206     }
207 elmex 1.1
208 root 1.5 /* no matter what, we fry the corpse. */
209     if (temp && temp->map)
210     {
211     /* replace corpse object with a burning object */
212 root 1.6 newob = arch_to_object (archetype::find ("burnout"));
213 root 1.5 if (newob != NULL)
214     {
215     newob->x = temp->x;
216     newob->y = temp->y;
217     insert_ob_in_map (newob, temp->map, op, 0);
218     }
219     leveldead = temp->level;
220 root 1.11 temp->remove ();
221     temp->destroy (0);
222 root 1.5 }
223    
224     if (resurrection_fails (clevel, leveldead))
225     {
226     if (spell->randomitems)
227     {
228     treasure *t;
229    
230     for (t = spell->randomitems->items; t; t = t->next)
231     {
232     summon_hostile_monsters (op, t->nrof, t->item->name);
233 root 1.2 }
234 elmex 1.1
235 root 1.2 }
236 root 1.5 return 1;
237 elmex 1.1
238 root 1.5 }
239     else
240     {
241     return resurrect_player (op, name_to_resurrect, spell);
242 elmex 1.1 }
243    
244 root 1.5 return 1;
245 elmex 1.1 }
246    
247    
248 root 1.5 int
249     resurrection_fails (int levelcaster, int leveldead)
250 elmex 1.1 {
251 root 1.5 int chance = 9;
252    
253     /* scheme: equal in level, 50% success.
254     * +5 % for each level below, -5% for each level above.
255     * minimum 20%
256     */
257     chance += levelcaster - leveldead;
258     if (chance < 4)
259     chance = 4;
260     if (chance > rndm (0, 19))
261     return 0; /* resurrection succeeds */
262     return 1;
263 elmex 1.1 }
264    
265 root 1.5 void
266     dead_player (object *op)
267 elmex 1.1 {
268 root 1.5 char filename[MAX_BUF];
269     char newname[MAX_BUF];
270     char path[MAX_BUF];
271    
272     /* set up our paths/strings... */
273     sprintf (path, "%s/%s/%s/%s", settings.localdir, settings.playerdir, &op->name, &op->name);
274    
275     strcpy (filename, path);
276     strcat (filename, ".pl");
277     strcpy (newname, filename);
278     strcat (newname, ".dead");
279    
280     if (rename (filename, newname) != 0)
281     {
282     LOG (llevError, "Cannot rename dead player's file %s into %s: %s\n", filename, newname, strerror (errno));
283 elmex 1.1 }
284     }
285    
286    
287    
288 root 1.5 void
289     dead_character (const char *name)
290     {
291     char buf[MAX_BUF];
292     char buf2[MAX_BUF];
293    
294     sprintf (buf, "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, name, name);
295     /* peterm: create a .dead filename.... ***.pl.dead */
296     strcpy (buf2, buf);
297     strcat (buf, ".dead");
298     if (rename (buf2, buf) == -1)
299     {
300     LOG (llevError, "Cannot rename dead player's file %s into %s: %s\n", buf2, buf, strerror (errno));
301 elmex 1.1 }
302     }
303    
304    
305 root 1.5 int
306     dead_player_exists (const char *name)
307     {
308     char buf[MAX_BUF];
309 elmex 1.1
310 root 1.5 sprintf (buf, "%s/%s/%s/%s", settings.localdir, settings.playerdir, name, name);
311     strcat (buf, ".pl.dead");
312     return !(access (buf, 0));
313 elmex 1.1 }