ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/resurrection.C
Revision: 1.23
Committed: Sun Jul 1 05:00:20 2007 UTC (16 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_2, rel-2_3
Changes since 1.22: +10 -11 lines
Log Message:
- upgrade crossfire trt to the GPL version 3 (hopefully correctly).
- add a single file covered by the GNU Affero General Public License
  (which is not yet released, so I used the current draft, which is
  legally a bit wavy, but its likely better than nothing as it expresses
  direct intent by the authors, and we can upgrade as soon as it has been
  released).
  * this should ensure availability of source code for the server at least
    and hopefully also archetypes and maps even when modified versions
    are not being distributed, in accordance of section 13 of the agplv3.

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.21 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 pippijn 1.19 *
4 root 1.21 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5     * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6     * Copyright (©) 1992,2007 Frank Tore Johansen
7 pippijn 1.19 *
8 root 1.23 * Crossfire TRT 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 3 of the License, or
11     * (at your option) any later version.
12 pippijn 1.19 *
13 root 1.23 * 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 pippijn 1.19 *
18 root 1.23 * You should have received a copy of the GNU General Public License
19     * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 root 1.21 *
21     * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 pippijn 1.19 */
23 elmex 1.1
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 /* name of the person to resurrect and which spell was used
33     * to resurrect
34     */
35 root 1.5 static int
36     resurrect_player (object *op, char *playername, object *spell)
37 elmex 1.1 {
38 root 1.5 FILE *deadplayer, *liveplayer;
39    
40     char oldname[MAX_BUF];
41     char newname[MAX_BUF];
42     char path[MAX_BUF];
43     char buf[MAX_BUF];
44     char buf2[MAX_BUF];
45     const char *race = NULL;
46     sint64 exp;
47     int Con;
48    
49     /* reincarnation, which changes the race */
50     if (spell->race)
51     {
52 root 1.20 treasurelist *tl = treasurelist::find (spell->race);
53 root 1.5 treasure *t;
54     int value;
55    
56     if (!tl)
57     {
58     LOG (llevError, "resurrect_player: race set to %s, but no treasurelist of that name!\n", &spell->race);
59     return 0;
60     }
61 root 1.20
62 root 1.5 value = RANDOM () % tl->total_chance;
63 root 1.20
64 root 1.5 for (t = tl->items; t; t = t->next)
65     {
66     value -= t->chance;
67     if (value < 0)
68     break;
69     }
70 root 1.20
71 elmex 1.16 if (!t || !t->item)
72 root 1.5 {
73     LOG (llevError, "resurrect_player: got null treasure from treasurelist %s!\n", &spell->race);
74     return 0;
75     }
76 root 1.20
77 root 1.22 race = t->item->archname;
78 root 1.5 }
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 root 1.22 summon_hostile_monsters (op, t->nrof, t->item->archname);
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 }