Crossfire Server, Branches 1.12  R18729
resurrection.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_resurrection_c =
3  * "$Id: resurrection.c 11578 2009-02-23 22:02:27Z lalo $";
4  */
5 
6 /*
7  CrossFire, A Multiplayer game for X-windows
8 
9  Copyright (C) 2006 Mark Wedel & Crossfire Development Team
10  Copyright (C) 1992 Frank Tore Johansen
11 
12  This program is free software; you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation; either version 2 of the License, or
15  (at your option) any later version.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 
26  The authors can be reached via e-mail at crossfire-devel@real-time.com
27 */
28 
36 /* the contents of this file were create solely by peterm@soda.berkeley.edu
37  all of the above disclaimers apply. */
38 
39 #include <global.h>
40 #ifndef __CEXTRACT__
41 #include <sproto.h>
42 #endif
43 #include <spells.h>
44 #include <errno.h>
45 
46 static int resurrection_fails(int levelcaster, int leveldead);
47 
62 static int resurrect_player(object *op, char *playername, object *spell) {
63  FILE *deadplayer, *liveplayer;
64 
65  char oldname[MAX_BUF];
66  char newname[MAX_BUF];
67  char path[MAX_BUF];
68  char buf[MAX_BUF];
69  char buf2[MAX_BUF];
70  const char *race = NULL;
71  sint64 exp;
72  int Con;
73 
74  /* reincarnation, which changes the race */
75  if (spell->race) {
76  treasurelist *tl = find_treasurelist(spell->race);
77  treasure *t;
78  int value;
79 
80  if (!tl) {
81  LOG(llevError, "resurrect_player: race set to %s, but no treasurelist of that name!\n", spell->race);
82  return 0;
83  }
84  value = RANDOM()%tl->total_chance;
85  for (t = tl->items; t; t = t->next) {
86  value -= t->chance;
87  if (value < 0)
88  break;
89  }
90  if (!t) {
91  LOG(llevError, "resurrect_player: got null treasure from treasurelist %s!\n", spell->race);
92  return 0;
93  }
94  race = t->item->name;
95  }
96 
97  /* set up our paths/strings... */
98  snprintf(path, sizeof(path), "%s/%s/%s/%s", settings.localdir, settings.playerdir, playername, playername);
99 
100  strcpy(newname, path);
101  strcat(newname, ".pl");
102 
103  strcpy(oldname, newname);
104  strcat(oldname, ".dead");
105 
106  if (!(deadplayer = fopen(oldname, "r"))) {
108  "The soul of %s cannot be reached.",
109  "The soul of %s cannot be reached.",
110  playername);
111  return 0;
112  }
113 
114  if (!access(newname, 0)) {
116  "The soul of %s has already been reborn!",
117  "The soul of %s has already been reborn!",
118  playername);
119  fclose(deadplayer);
120  return 0;
121  }
122 
123  if (!(liveplayer = fopen(newname, "w"))) {
125  "The soul of %s cannot be re-embodied at the moment.",
126  "The soul of %s cannot be re-embodied at the moment.",
127  playername);
128  LOG(llevError, "Cannot write player in resurrect_player!\n");
129  fclose(deadplayer);
130  return 0;
131  }
132 
133  while (!feof(deadplayer)) {
134  fgets(buf, 255, deadplayer);
135  sscanf(buf, "%s", buf2);
136  if (!(strcmp(buf2, "exp"))) {
137  sscanf(buf, "%s %"FMT64, buf2, &exp);
138  if (spell->stats.exp) {
139  exp -= exp/spell->stats.exp;
140  snprintf(buf, sizeof(buf), "exp %"FMT64"\n", exp);
141  }
142  }
143  if (!(strcmp(buf2, "Con"))) {
144  sscanf(buf, "%s %d", buf2, &Con);
145  Con -= spell->stats.Con;
146  if (Con < 1)
147  Con = 1;
148  snprintf(buf, sizeof(buf), "Con %d\n", Con);
149  }
150  if (race && !strcmp(buf2, "race")) {
151  snprintf(buf, sizeof(buf), "race %s\n", race);
152  }
153  fputs(buf, liveplayer);
154  }
155  fclose(liveplayer);
156  fclose(deadplayer);
157  unlink(oldname);
159  "%s lives again!",
160  "%s lives again!",
161  playername);
162 
163  return 1;
164 }
165 
186 int cast_raise_dead_spell(object *op, object *caster, object *spell, int dir, const char *arg) {
187  object *temp, *newob;
188  char name_to_resurrect[MAX_BUF];
189  int leveldead = 25, mflags, clevel;
190  sint16 sx, sy;
191  mapstruct *m;
192 
193  clevel = caster_level(caster, spell);
194 
195  if (spell->last_heal) {
196  if (!arg) {
198  "Cast %s on who?",
199  "Cast %s on who?",
200  spell->name);
201  return 0;
202  }
203  strcpy(name_to_resurrect, arg);
204  temp = NULL;
205  } else {
206  sx = op->x+freearr_x[dir];
207  sy = op->y+freearr_y[dir];
208  m = op->map;
209  mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
210  if (mflags&P_OUT_OF_MAP)
211  temp = NULL;
212  else {
213  /* First we need to find a corpse, if any. */
214  /* If no object, temp will be set to NULL */
215  for (temp = GET_MAP_OB(m, sx, sy); temp != NULL; temp = temp->above)
216  /* If it is corpse, this must be what we want to raise */
217  if (temp->type == CORPSE)
218  break;
219  }
220 
221  if (temp == NULL) {
223  "You need a body for this spell.", NULL);
224  return 0;
225  }
226  strcpy(name_to_resurrect, temp->name);
227  }
228 
229  /* no matter what, we fry the corpse. */
230  if (temp && temp->map) {
231  /* replace corpse object with a burning object */
232  newob = arch_to_object(find_archetype("burnout"));
233  if (newob != NULL) {
234  newob->x = temp->x;
235  newob->y = temp->y;
236  insert_ob_in_map(newob, temp->map, op, 0);
237  }
238  leveldead = temp->level;
239  remove_ob(temp);
240  free_object(temp);
241  }
242 
243  if (resurrection_fails(clevel, leveldead)) {
244  if (spell->randomitems) {
245  treasure *t;
246 
247  for (t = spell->randomitems->items; t; t = t->next) {
248  summon_hostile_monsters(op, t->nrof, t->item->name);
249  }
250 
251  }
252  return 1;
253  } else {
254  return resurrect_player(op, name_to_resurrect, spell);
255  }
256  /* Unreachable */
257 }
258 
274 static int resurrection_fails(int levelcaster, int leveldead) {
275  int chance = 9;
276 
277  chance += levelcaster-leveldead;
278  if (chance < 4)
279  chance = 4;
280  if (chance > rndm(0, 19))
281  return 0; /* resurrection succeeds */
282  return 1;
283 }
284 
291 void dead_player(object *op) {
292  char filename[MAX_BUF];
293  char newname[MAX_BUF];
294  char path[MAX_BUF];
295 
296  /* set up our paths/strings... */
297  snprintf(path, sizeof(path), "%s/%s/%s/%s", settings.localdir, settings.playerdir, op->name, op->name);
298 
299  strcpy(filename, path);
300  strcat(filename, ".pl");
301  strcpy(newname, filename);
302  strcat(newname, ".dead");
303 
304  if (rename(filename, newname) != 0) {
305  LOG(llevError, "Cannot rename dead player's file %s into %s: %s\n", filename, newname, strerror_local(errno, path, sizeof(path)));
306  }
307 }
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, sint16 x, sint16 y, sint16 *nx, sint16 *ny)
Definition: map.c:330
archetype * find_archetype(const char *name)
Definition: arch.c:700
signed short sint16
Definition: global.h:72
const char * race
Definition: object.h:171
int caster_level(const object *caster, const object *spell)
Definition: spell_util.c:237
sint16 total_chance
Definition: treasure.h:113
#define CORPSE
Definition: define.h:329
treasurelist * find_treasurelist(const char *name)
Definition: treasure.c:295
const char * playerdir
Definition: global.h:336
sint32 last_heal
Definition: object.h:208
#define MSG_TYPE_SPELL_FAILURE
Definition: newclient.h:548
struct treasureliststruct * randomitems
Definition: object.h:236
short freearr_x[SIZEOFFREE]
Definition: object.c:75
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
Definition: standalone.c:171
#define MSG_TYPE_SPELL
Definition: newclient.h:333
sint64 exp
Definition: living.h:88
struct obj * above
Definition: object.h:146
sint16 x
Definition: object.h:179
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
Definition: standalone.c:175
struct archt * item
Definition: treasure.h:93
sint8 Con
Definition: living.h:78
short freearr_y[SIZEOFFREE]
Definition: object.c:81
int rndm(int min, int max)
Definition: utils.c:174
void remove_ob(object *op)
Definition: object.c:1515
struct mapdef * map
Definition: object.h:155
int summon_hostile_monsters(object *op, int n, const char *monstername)
Definition: spell_util.c:970
static int resurrection_fails(int levelcaster, int leveldead)
Definition: resurrection.c:274
const char * name
Definition: object.h:167
#define P_OUT_OF_MAP
Definition: map.h:272
sint16 y
Definition: object.h:179
#define MAX_BUF
Definition: define.h:81
object * insert_ob_in_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1992
struct treasurestruct * items
Definition: treasure.h:119
void dead_player(object *op)
Definition: resurrection.c:291
int snprintf(char *dest, int max, const char *format,...)
Definition: porting.c:498
const char * localdir
Definition: global.h:335
living stats
Definition: object.h:219
#define unlink(__a)
Definition: win32.h:67
struct Settings settings
Definition: init.c:48
#define MSG_TYPE_SPELL_SUCCESS
Definition: newclient.h:550
#define GET_MAP_OB(M, X, Y)
Definition: map.h:193
#define NDI_UNIQUE
Definition: newclient.h:219
int cast_raise_dead_spell(object *op, object *caster, object *spell, int dir, const char *arg)
Definition: resurrection.c:186
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
uint16 nrof
Definition: treasure.h:105
static int resurrect_player(object *op, char *playername, object *spell)
Definition: resurrection.c:62
void free_object(object *ob)
Definition: object.c:1238
Definition: map.h:346
char * strerror_local(int errnum, char *buf, size_t size)
Definition: porting.c:525
struct treasurestruct * next
Definition: treasure.h:95
sint16 level
Definition: object.h:202
object * arch_to_object(archetype *at)
Definition: arch.c:576
uint8 chance
Definition: treasure.h:99
const char * name
Definition: object.h:322
uint8 type
Definition: object.h:189