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

# Content
1 /*
2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 *
4 * 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 *
8 * 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 *
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, see <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 */
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 #include <sproto.h>
29 #include <spells.h>
30 #include <errno.h>
31
32 /* name of the person to resurrect and which spell was used
33 * to resurrect
34 */
35 static int
36 resurrect_player (object *op, char *playername, object *spell)
37 {
38 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 treasurelist *tl = treasurelist::find (spell->race);
53 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
62 value = RANDOM () % tl->total_chance;
63
64 for (t = tl->items; t; t = t->next)
65 {
66 value -= t->chance;
67 if (value < 0)
68 break;
69 }
70
71 if (!t || !t->item)
72 {
73 LOG (llevError, "resurrect_player: got null treasure from treasurelist %s!\n", &spell->race);
74 return 0;
75 }
76
77 race = t->item->archname;
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
89 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 sscanf (buf, "%s %" SCNd64, buf2, &exp);
117 if (spell->stats.exp)
118 {
119 exp -= exp / spell->stats.exp;
120 sprintf (buf, "exp %" PRId64 "\n", exp);
121 }
122 }
123 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
142 return 1;
143 }
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 int
153 cast_raise_dead_spell (object *op, object *caster, object *spell, int dir, const char *arg)
154 {
155 object *temp, *newob;
156 char name_to_resurrect[MAX_BUF];
157 int leveldead = 25, mflags, clevel;
158 sint16 sx, sy;
159 maptile *m;
160
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 }
170 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 temp = NULL;
181 else
182 {
183 /* First we need to find a corpse, if any. */
184 /* If no object, temp will be set to NULL */
185 for (temp = GET_MAP_OB (m, sx, sy); temp != NULL; temp = temp->above)
186 /* 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
199 /* no matter what, we fry the corpse. */
200 if (temp && temp->map)
201 {
202 /* replace corpse object with a burning object */
203 newob = arch_to_object (archetype::find ("burnout"));
204 if (newob)
205 newob->insert_at (temp, op);
206
207 leveldead = temp->level;
208 temp->destroy ();
209 }
210
211 if (resurrection_fails (clevel, leveldead))
212 {
213 if (spell->randomitems)
214 for (treasure *t = spell->randomitems->items; t; t = t->next)
215 if (t->item)
216 summon_hostile_monsters (op, t->nrof, t->item->archname);
217
218 return 1;
219
220 }
221 else
222 return resurrect_player (op, name_to_resurrect, spell);
223 }
224
225
226 int
227 resurrection_fails (int levelcaster, int leveldead)
228 {
229 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 }
242
243 void
244 dead_player (object *op)
245 {
246 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 }
262 }
263
264
265
266 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 }
280 }
281
282
283 int
284 dead_player_exists (const char *name)
285 {
286 char buf[MAX_BUF];
287
288 sprintf (buf, "%s/%s/%s/%s", settings.localdir, settings.playerdir, name, name);
289 strcat (buf, ".pl.dead");
290 return !(access (buf, 0));
291 }