ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/resurrection.C
Revision: 1.1
Committed: Sun Aug 13 17:16:04 2006 UTC (17 years, 9 months ago) by elmex
Content type: text/plain
Branch: MAIN
Log Message:
Made server compile with C++.
Removed cfanim plugin and crossedit.
C++ here we come.

File Contents

# User Rev Content
1 elmex 1.1 /*
2     * static char *rcsid_resurrection_c =
3     * "$Id$";
4     */
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     treasurelist *tl = find_treasurelist(spell->race);
68     treasure *t;
69     int value;
70     if (!tl) {
71     LOG(llevError,"resurrect_player: race set to %s, but no treasurelist of that name!\n", spell->race);
72     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     LOG(llevError,"resurrect_player: got null treasure from treasurelist %s!\n", spell->race);
81     return 0;
82     }
83     race = t->item->name;
84     }
85    
86     /* set up our paths/strings... */
87     sprintf(path,"%s/%s/%s/%s",settings.localdir,settings.playerdir,playername,
88     playername);
89    
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     new_draw_info_format(NDI_UNIQUE, 0, op,
98     "The soul of %s cannot be reached.",playername);
99     return 0;
100     }
101    
102     if(!access(newname,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     }
134     }
135     if(! (strcmp(buf2,"Con"))) {
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     }
146     fclose(liveplayer);
147     fclose(deadplayer);
148     unlink(oldname);
149     new_draw_info_format(NDI_UNIQUE, 0, op,
150     "%s lives again!",playername);
151    
152     return 1;
153     }
154    
155    
156     /* raise_dead by peterm and mehlhaff@soda.berkeley.edu
157     * op -- who is doing the resurrecting
158     * spell - spell object
159     * dir -- direction the spell is cast
160     * corpseobj - corpse to raise - can be null, in which case this function will find it
161     */
162     int cast_raise_dead_spell(object *op, object *caster, object *spell, int dir, const char *arg)
163     {
164     object *temp, *newob;
165     char name_to_resurrect[MAX_BUF];
166     int leveldead=25, mflags, clevel;
167     sint16 sx, sy;
168     mapstruct *m;
169    
170     clevel = caster_level(caster, spell);
171    
172     if (spell->last_heal) {
173     if (!arg) {
174     new_draw_info_format(NDI_UNIQUE, 0,op,"Cast %s on who?", spell->name);
175     return 0;
176     }
177     strcpy(name_to_resurrect, arg);
178     temp = NULL;
179     } else {
180     sx = op->x+freearr_x[dir];
181     sy = op->y+freearr_y[dir];
182     m = op->map;
183     mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
184     if (mflags & P_OUT_OF_MAP)
185     temp=NULL;
186     else {
187     /* First we need to find a corpse, if any. */
188     /* If no object, temp will be set to NULL */
189     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 */
191     if(temp->type == CORPSE)
192     break;
193     }
194    
195     if(temp == NULL) {
196     new_draw_info(NDI_UNIQUE, 0,op, "You need a body for this spell.");
197     return 0;
198     }
199     strcpy(name_to_resurrect, temp->name );
200     }
201    
202     /* no matter what, we fry the corpse. */
203     if( temp && temp->map){
204     /* replace corpse object with a burning object */
205     newob = arch_to_object(find_archetype("burnout"));
206     if(newob != NULL){
207     newob->x = temp->x;
208     newob->y = temp->y;
209     insert_ob_in_map( newob, temp->map, op,0);
210     }
211     leveldead=temp->level;
212     remove_ob(temp);
213     free_object(temp);
214     }
215    
216     if(resurrection_fails(clevel,leveldead)) {
217     if (spell->randomitems) {
218     treasure *t;
219    
220     for (t=spell->randomitems->items; t; t=t->next) {
221     summon_hostile_monsters(op, t->nrof, t->item->name);
222     }
223    
224     }
225     return 1;
226    
227     } else {
228     return resurrect_player(op,name_to_resurrect,spell);
229     }
230    
231     return 1;
232     }
233    
234    
235     int resurrection_fails(int levelcaster,int leveldead)
236     {
237     int chance=9;
238     /* scheme: equal in level, 50% success.
239     * +5 % for each level below, -5% for each level above.
240     * minimum 20%
241     */
242     chance+=levelcaster-leveldead;
243     if(chance<4) chance=4;
244     if(chance>rndm(0, 19)) return 0; /* resurrection succeeds */
245     return 1;
246     }
247    
248     void dead_player(object *op)
249     {
250     char filename[MAX_BUF];
251     char newname[MAX_BUF];
252     char path[MAX_BUF];
253    
254     /* set up our paths/strings... */
255     sprintf(path,"%s/%s/%s/%s",settings.localdir,settings.playerdir,op->name,
256     op->name);
257    
258     strcpy(filename,path);
259     strcat(filename,".pl");
260     strcpy(newname,filename);
261     strcat(newname,".dead");
262    
263     if(rename(filename,newname) != 0) {
264     LOG(llevError, "Cannot rename dead player's file %s into %s: %s\n", filename, newname, strerror_local(errno));
265     }
266     }
267    
268    
269    
270     void dead_character(const char *name) {
271     char buf[MAX_BUF];
272     char buf2[MAX_BUF];
273    
274     sprintf(buf,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,name, name);
275     /* peterm: create a .dead filename.... ***.pl.dead */
276     strcpy(buf2,buf);
277     strcat(buf,".dead");
278     if(rename(buf2,buf)== -1){
279     LOG(llevError, "Cannot rename dead player's file %s into %s: %s\n", buf2, buf, strerror_local(errno));
280     }
281     }
282    
283    
284     int dead_player_exists(const char *name) {
285     char buf[MAX_BUF];
286    
287     sprintf(buf,"%s/%s/%s/%s",settings.localdir,settings.playerdir,name, name);
288     strcat(buf,".pl.dead");
289     return !(access(buf,0));
290     }
291    
292