ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/resurrection.C
Revision: 1.17
Committed: Sat Jan 6 14:42:31 2007 UTC (17 years, 5 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.16: +1 -0 lines
Log Message:
added some copyrights

File Contents

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