00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00036
00037
00038
00039 #include <global.h>
00040 #ifndef __CEXTRACT__
00041 #include <sproto.h>
00042 #endif
00043 #include <spells.h>
00044 #include <errno.h>
00045
00046 static int resurrection_fails(int levelcaster, int leveldead);
00047
00062 static int resurrect_player(object *op, char *playername, object *spell) {
00063 FILE *deadplayer, *liveplayer;
00064
00065 char oldname[MAX_BUF];
00066 char newname[MAX_BUF];
00067 char path[MAX_BUF];
00068 char buf[MAX_BUF];
00069 char buf2[MAX_BUF];
00070 const char *race = NULL;
00071 sint64 exp;
00072 int Con;
00073
00074
00075 if (spell->race) {
00076 treasurelist *tl = find_treasurelist(spell->race);
00077 treasure *t;
00078 int value;
00079
00080 if (!tl) {
00081 LOG(llevError, "resurrect_player: race set to %s, but no treasurelist of that name!\n", spell->race);
00082 return 0;
00083 }
00084 value = RANDOM()%tl->total_chance;
00085 for (t = tl->items; t; t = t->next) {
00086 value -= t->chance;
00087 if (value < 0)
00088 break;
00089 }
00090 if (!t) {
00091 LOG(llevError, "resurrect_player: got null treasure from treasurelist %s!\n", spell->race);
00092 return 0;
00093 }
00094 race = t->item->name;
00095 }
00096
00097
00098 snprintf(path, sizeof(path), "%s/%s/%s/%s", settings.localdir, settings.playerdir, playername, playername);
00099
00100 strcpy(newname, path);
00101 strcat(newname, ".pl");
00102
00103 strcpy(oldname, newname);
00104 strcat(oldname, ".dead");
00105
00106 if (!(deadplayer = fopen(oldname, "r"))) {
00107 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_SPELL, MSG_TYPE_SPELL_FAILURE,
00108 "The soul of %s cannot be reached.",
00109 "The soul of %s cannot be reached.",
00110 playername);
00111 return 0;
00112 }
00113
00114 if (!access(newname, 0)) {
00115 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_SPELL, MSG_TYPE_SPELL_FAILURE,
00116 "The soul of %s has already been reborn!",
00117 "The soul of %s has already been reborn!",
00118 playername);
00119 fclose(deadplayer);
00120 return 0;
00121 }
00122
00123 if (!(liveplayer = fopen(newname, "w"))) {
00124 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_SPELL, MSG_TYPE_SPELL_FAILURE,
00125 "The soul of %s cannot be re-embodied at the moment.",
00126 "The soul of %s cannot be re-embodied at the moment.",
00127 playername);
00128 LOG(llevError, "Cannot write player in resurrect_player!\n");
00129 fclose(deadplayer);
00130 return 0;
00131 }
00132
00133 while (!feof(deadplayer)) {
00134 fgets(buf, 255, deadplayer);
00135 sscanf(buf, "%s", buf2);
00136 if (!(strcmp(buf2, "exp"))) {
00137 sscanf(buf, "%s %"FMT64, buf2, &exp);
00138 if (spell->stats.exp) {
00139 exp -= exp/spell->stats.exp;
00140 snprintf(buf, sizeof(buf), "exp %"FMT64"\n", exp);
00141 }
00142 }
00143 if (!(strcmp(buf2, "Con"))) {
00144 sscanf(buf, "%s %d", buf2, &Con);
00145 Con -= spell->stats.Con;
00146 if (Con < 1)
00147 Con = 1;
00148 snprintf(buf, sizeof(buf), "Con %d\n", Con);
00149 }
00150 if (race && !strcmp(buf2, "race")) {
00151 snprintf(buf, sizeof(buf), "race %s\n", race);
00152 }
00153 fputs(buf, liveplayer);
00154 }
00155 fclose(liveplayer);
00156 fclose(deadplayer);
00157 unlink(oldname);
00158 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_SPELL, MSG_TYPE_SPELL_SUCCESS,
00159 "%s lives again!",
00160 "%s lives again!",
00161 playername);
00162
00163 return 1;
00164 }
00165
00186 int cast_raise_dead_spell(object *op, object *caster, object *spell, int dir, const char *arg) {
00187 object *temp, *newob;
00188 char name_to_resurrect[MAX_BUF];
00189 int leveldead = 25, mflags, clevel;
00190 sint16 sx, sy;
00191 mapstruct *m;
00192
00193 clevel = caster_level(caster, spell);
00194
00195 if (spell->last_heal) {
00196 if (!arg) {
00197 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_SPELL, MSG_TYPE_SPELL_FAILURE,
00198 "Cast %s on who?",
00199 "Cast %s on who?",
00200 spell->name);
00201 return 0;
00202 }
00203 strcpy(name_to_resurrect, arg);
00204 temp = NULL;
00205 } else {
00206 sx = op->x+freearr_x[dir];
00207 sy = op->y+freearr_y[dir];
00208 m = op->map;
00209 mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
00210 if (mflags&P_OUT_OF_MAP)
00211 temp = NULL;
00212 else {
00213
00214
00215 for (temp = GET_MAP_OB(m, sx, sy); temp != NULL; temp = temp->above)
00216
00217 if (temp->type == CORPSE)
00218 break;
00219 }
00220
00221 if (temp == NULL) {
00222 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_SPELL, MSG_TYPE_SPELL_FAILURE,
00223 "You need a body for this spell.", NULL);
00224 return 0;
00225 }
00226 strcpy(name_to_resurrect, temp->name);
00227 }
00228
00229
00230 if (temp && temp->map) {
00231
00232 newob = arch_to_object(find_archetype("burnout"));
00233 if (newob != NULL) {
00234 newob->x = temp->x;
00235 newob->y = temp->y;
00236 insert_ob_in_map(newob, temp->map, op, 0);
00237 }
00238 leveldead = temp->level;
00239 remove_ob(temp);
00240 free_object(temp);
00241 }
00242
00243 if (resurrection_fails(clevel, leveldead)) {
00244 if (spell->randomitems) {
00245 treasure *t;
00246
00247 for (t = spell->randomitems->items; t; t = t->next) {
00248 summon_hostile_monsters(op, t->nrof, t->item->name);
00249 }
00250
00251 }
00252 return 1;
00253 } else {
00254 return resurrect_player(op, name_to_resurrect, spell);
00255 }
00256
00257 }
00258
00274 static int resurrection_fails(int levelcaster, int leveldead) {
00275 int chance = 9;
00276
00277 chance += levelcaster-leveldead;
00278 if (chance < 4)
00279 chance = 4;
00280 if (chance > rndm(0, 19))
00281 return 0;
00282 return 1;
00283 }
00284
00291 void dead_player(object *op) {
00292 char filename[MAX_BUF];
00293 char newname[MAX_BUF];
00294 char path[MAX_BUF];
00295
00296
00297 snprintf(path, sizeof(path), "%s/%s/%s/%s", settings.localdir, settings.playerdir, op->name, op->name);
00298
00299 strcpy(filename, path);
00300 strcat(filename, ".pl");
00301 strcpy(newname, filename);
00302 strcat(newname, ".dead");
00303
00304 if (rename(filename, newname) != 0) {
00305 LOG(llevError, "Cannot rename dead player's file %s into %s: %s\n", filename, newname, strerror_local(errno, path, sizeof(path)));
00306 }
00307 }