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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines