ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/resurrection.C
Revision: 1.14
Committed: Tue Dec 26 08:55:00 2006 UTC (17 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.13: +1 -11 lines
Log Message:
replace update_ob_speed by ->set_speed

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