ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/resurrection.C
(Generate patch)

Comparing deliantra/server/server/resurrection.C (file contents):
Revision 1.1 by elmex, Sun Aug 13 17:16:04 2006 UTC vs.
Revision 1.17 by pippijn, Sat Jan 6 14:42:31 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines