ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/resurrection.C
Revision: 1.4
Committed: Sun Sep 3 00:18:42 2006 UTC (17 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.3: +8 -16 lines
Log Message:
THIS CODE WILL NOT COMPILE
use the STABLE tag instead.

- major changes in object lifetime and memory management
- replaced manual refcounting by shstr class
- removed quest system
- many optimisations
- major changes

File Contents

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