/* * Birth * ======= * Birth and Rebirth Module * Written by Keolah for Rogue Winds 2.0 * * You may not use or distribute any of this code without the * explicit permission of the code maintainer, Heather Dunn (Keolah) */ #include <sys/types.h> #include <sys/stat.h> #include <ctype.h> #include <errno.h> #include <stdio.h> #include <time.h> #include <string.h> #include <fcntl.h> #include <signal.h> #include <stdarg.h> #include "mud.h" /* from handler.c */ extern SPECIES_DATA *find_species(char *name); /* from misc.c */ extern sh_int get_full(CHAR_DATA *ch); void birth(CHAR_DATA *ch); int count_tokens(char *str) { int i, count; count = 0; for (i = 0;i < MAX_STRING_LENGTH;i++) { if (str[i] == '\0') break; if (str[i] == ',') count++; } return count; } char *find_token(char *token, char *str, int num) { int i, count, found, n; count = 0; n = 0; token = STRALLOC("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); found = FALSE; for (i = 0;i < MAX_STRING_LENGTH;i++) { if (str[i] == '\0') break; if (str[i] == ',') { count++; if (found) break; } if (count == num && !found) { found = TRUE; } if (found && str[i] != ',') { token[n] = str[i]; n++; } } token[n] = '\0'; return token; } void set_race(CHAR_DATA *ch, bool died) { SPECIES_DATA *species; OBJ_DATA *obj; char buf[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; int i; STRFREE(ch->species); ch->species = STRALLOC(ch->nation->name); species = find_species(ch->nation->species); ch->race = species->skill_set; STRFREE(ch->pcdata->eyes); if (ch->nation->eyes) { i = count_tokens(ch->nation->eyes); i = number_range(0,i); ch->pcdata->eyes = STRALLOC(find_token(ch->pcdata->eyes, ch->nation->eyes, i)); } STRFREE(ch->pcdata->hair); if (ch->nation->hair) { i = count_tokens(ch->nation->hair); i = number_range(0,i); ch->pcdata->hair = STRALLOC(find_token(ch->pcdata->hair, ch->nation->hair, i)); } STRFREE(ch->pcdata->skin_color); if (ch->nation->skin_color) { i = count_tokens(ch->nation->skin_color); i = number_range(0,i); ch->pcdata->skin_color = STRALLOC(find_token(ch->pcdata->skin_color, ch->nation->skin_color, i)); } STRFREE(ch->pcdata->skin_type); if (ch->nation->skin_type) ch->pcdata->skin_type = STRALLOC(ch->nation->skin_type); STRFREE(ch->pcdata->extra_color); if (ch->nation->extra_color) { i = count_tokens(ch->nation->extra_color); i = number_range(0,i); ch->pcdata->extra_color = STRALLOC(find_token(ch->pcdata->extra_color, ch->nation->extra_color, i)); } STRFREE(ch->pcdata->extra_type); if (ch->nation->extra_type) { i = count_tokens(ch->nation->extra_type); i = number_range(0,i); ch->pcdata->extra_type = STRALLOC(find_token(ch->pcdata->extra_type, ch->nation->extra_type, i)); } ch->max_hit = UMAX(20, ch->nation->hit * get_curr_con(ch)); ch->max_mana = UMAX(20, ch->nation->mana * get_curr_int(ch)); ch->max_move = UMAX(20, 20 * get_curr_end(ch)); ch->hit = ch->max_hit; ch->mana = ch->max_mana; ch->move = ch->max_move; ch->height = number_range(ch->nation->height *.9, ch->nation->height *1.1); ch->weight = get_height_weight(ch); if (ch->height == 0) ch->height = 1; if (ch->weight == 0) ch->weight = 1; ch->affected_by = ch->nation->affected; fix_char(ch); update_aris(ch); ch->pcdata->condition[COND_FULL] = get_full(ch) / 2; ch->pcdata->condition[COND_THIRST] = get_full(ch) / 2; ch->xflags = ch->nation->parts; check_bodyparts(ch); if (died) { ch->pcdata->weapon[ch->nation->weapon] = UMAX(30, ch->pcdata->weapon[ch->nation->weapon]); ch->pcdata->age_adjust = ch->nation->base_age; STRFREE(ch->last_taken); ch->last_taken = STRALLOC("being reborn"); WAIT_STATE(ch, PULSE_VIOLENCE*2); } /* If they're humanoid, give them a little equipment so they aren't naked * Warning, if you change the equipment in stockobj.are * remember to change it here as well. */ if (IS_SET(ch->xflags, 1 << PART_HANDS) && died) for (i = 0;i < 5;i++) { obj = NULL; if (i == 0) switch(ch->nation->weapon) { case SK_SWORD: switch (number_range(1,5)) { case 1: obj = create_object( get_obj_index( 29063 ), 0 ); /* broadsword */ break; case 2: obj = create_object( get_obj_index( 29031 ), 0 ); /* short sword */ break; case 3: obj = create_object( get_obj_index( 29033 ), 0 ); /* long sword */ break; case 4: obj = create_object( get_obj_index( 29034 ), 0 ); /* bastard sword */ break; case 5: obj = create_object( get_obj_index( 29035 ), 0 ); /* great sword */ break; } break; case SK_DAGGER: switch (number_range(1,3)) { case 1: obj = create_object( get_obj_index( 29030 ), 0 ); /* dagger */ break; case 2: obj = create_object( get_obj_index( 29031 ), 0 ); /* dirk */ break; case 3: obj = create_object( get_obj_index( 29019 ), 0 ); /* knife */ break; } break; case SK_AXE: switch (number_range(1,3)) { case 1: obj = create_object( get_obj_index( 29039 ), 0 ); /* battle axe */ break; case 2: obj = create_object( get_obj_index( 29038 ), 0 ); /* hand axe */ break; case 3: obj = create_object( get_obj_index( 29040 ), 0 ); /* greataxe */ break; } break; case SK_WHIP: switch (number_range(1,2)) { case 1: obj = create_object( get_obj_index( 29043 ), 0 ); /* whip */ break; case 2: obj = create_object( get_obj_index( 28936 ), 0 ); /* flail */ break; } break; case SK_MACE: switch (number_range(1,2)) { case 1: obj = create_object( get_obj_index( 29036 ), 0 ); /* mace */ break; case 2: obj = create_object( get_obj_index( 28926 ), 0 ); /* club */ break; } break; case SK_STAFF: switch (number_range(1,2)) { case 1: obj = create_object( get_obj_index( 29055 ), 0 ); /* quarterstaff */ break; case 2: obj = create_object( get_obj_index( 28955 ), 0 ); /* staff */ break; } break; case SK_HALBERD: switch (number_range(1,2)) { case 1: obj = create_object( get_obj_index( 29042 ), 0 ); /* halberd */ break; case 2: obj = create_object( get_obj_index( 28942 ), 0 ); /* glaive */ break; } break; case SK_SPEAR: switch (number_range(1,2)) { case 1: obj = create_object( get_obj_index( 29041 ), 0 ); /* spear */ break; case 2: obj = create_object( get_obj_index( 29091 ), 0 ); /* trident */ break; } break; case SK_POLEARM: switch (number_range(1,2)) { case 1: obj = create_object( get_obj_index( 28925 ), 0 ); /* scythe */ break; case 2: obj = create_object( get_obj_index( 29117 ), 0 ); /* sickle */ break; } break; case SK_BOW: obj = create_object( get_obj_index( 29047 ), 0 ); /* long bow */ break; case SK_FIREARMS: switch (number_range(1,3)) { case 1: obj = create_object( get_obj_index( 29049 ), 0 ); /* pistol */ break; case 2: obj = create_object( get_obj_index( 28939 ), 0 ); /* shotgun */ break; case 3: obj = create_object( get_obj_index( 28938 ), 0 ); /* rifle */ break; } break; case SK_CROSSBOW: obj = create_object( get_obj_index( 29045 ), 0 ); /* crossbow */ break; case SK_WAND: obj = create_object( get_obj_index( 29066 ), 0 ); /* wand */ break; } if (i == 1) { if (IS_SET(ch->xflags, 1 << PART_LEGS)) { switch (number_range(1,5)) { case 1: obj = create_object( get_obj_index( 28910 ), 0 ); /* pants */ break; case 2: obj = create_object( get_obj_index( 29016 ), 0 ); /* leggings */ break; case 3: obj = create_object( get_obj_index( 29018 ), 0 ); /* greaves */ break; case 4: obj = create_object( get_obj_index( 28901 ), 0 ); /* kilt */ break; case 5: obj = create_object( get_obj_index( 29083 ), 0 ); /* loincloth */ break; } } else { switch (number_range(1,5)) { case 1: obj = create_object( get_obj_index( 28917 ), 0 ); /* saddle */ break; case 2: obj = create_object( get_obj_index( 29064 ), 0 ); /* amulet */ break; case 3: obj = create_object( get_obj_index( 29061 ), 0 ); /* necklace */ break; case 4: obj = create_object( get_obj_index( 29110 ), 0 ); /* torc */ break; case 5: obj = create_object( get_obj_index( 29139 ), 0 ); /* scarf */ break; } } } if (i == 2) { if (IS_SET(ch->xflags, 1 << PART_FEET)) { switch (number_range(1,4)) { case 1: obj = create_object( get_obj_index( 29008 ), 0 ); /* boots */ break; case 2: obj = create_object( get_obj_index( 29009 ), 0 ); /* shod boots */ break; case 3: obj = create_object( get_obj_index( 28931 ), 0 ); /* sandals */ break; case 4: obj = create_object( get_obj_index( 29017 ), 0 ); /* socks */ break; } } else if (IS_SET(ch->xflags, 1 << PART_HOOVES)) { obj = create_object( get_obj_index( 29085 ), 0 ); /* horseshoes */ } } if (i == 3) { switch (number_range(1,5)) { case 1: obj = create_object( get_obj_index( 29109 ), 0 ); /* tunic */ break; case 2: obj = create_object( get_obj_index( 29013 ), 0 ); /* robe */ break; case 3: obj = create_object( get_obj_index( 29000 ), 0 ); /* chainmail */ break; case 4: obj = create_object( get_obj_index( 28911 ), 0 ); /* shirt */ break; case 5: obj = create_object( get_obj_index( 29014 ), 0 ); /* cloak */ break; } } if (i == 4) { switch (number_range(1,5)) { case 1: obj = create_object( get_obj_index( 29062 ), 0 ); /* pack */ break; case 2: obj = create_object( get_obj_index( 29072 ), 0 ); /* pouch */ break; case 3: obj = create_object( get_obj_index( 29073 ), 0 ); /* bag */ break; case 4: obj = create_object( get_obj_index( 29074 ), 0 ); /* chest */ break; case 5: obj = create_object( get_obj_index( 29075 ), 0 ); /* box */ break; } } if (obj) { MATERIAL_DATA *mat; AFFECT_DATA *paf; extern int top_affect; mat = first_material; while (mat) { if ((xIS_SET(obj->extra_flags, ITEM_METAL) && xIS_SET(mat->extra_flags, ITEM_METAL)) || (xIS_SET(obj->extra_flags, ITEM_FLAMMABLE) && xIS_SET(mat->extra_flags, ITEM_FLAMMABLE)) || (xIS_SET(obj->extra_flags, ITEM_ORGANIC) && xIS_SET(mat->extra_flags, ITEM_ORGANIC))) { if (number_percent() < mat->rarity) break; } mat = mat->next; } /* If we didn't find a good material, forget it */ if (!mat) { extract_obj(obj); } else { obj->material = mat; strcpy(buf, species->adj); strcat(buf, " "); strcat(buf, mat->name); sprintf(buf2, obj->short_descr, buf); one_argument(buf2, buf); STRFREE(obj->short_descr); obj->short_descr = STRALLOC(buf2); strcpy(buf, mat->name); sprintf(buf2, obj->description, buf); STRFREE(obj->description); obj->description = STRALLOC(capitalize(buf2)); strcpy(buf, obj->name); strcat(buf, " "); strcat(buf, mat->name); strcat(buf, " "); strcat(buf, species->adj); STRFREE(obj->name); obj->name=STRALLOC(buf); obj->value[2] = 100; xSET_BITS(obj->extra_flags, mat->extra_flags); obj->cost += number_fuzzy(mat->cost); obj->size = ch->height; obj->weight = UMAX(obj->weight + (ch->height - 66) / 10,1); for (paf = mat->first_affect; paf; paf = paf->next) { AFFECT_DATA *naf; CREATE(naf, AFFECT_DATA, 1); naf->type = paf->type; naf->duration = paf->duration; naf->location = paf->location; naf->modifier = paf->modifier; naf->bitvector = paf->bitvector; top_affect++; LINK(naf, obj->first_affect, obj->last_affect, next, prev); } obj_to_char(obj, ch); if (xIS_EMPTY(obj->parts)) do_wield(ch, obj->name); else equip_char(ch, obj); } } } } void choose_sex(CHAR_DATA *ch, char *argument) { int i; if (nifty_is_name("newbie", argument)) { do_chat(ch, argument); return; } if (!str_prefix(argument, "m")) ch->sex = SEX_MALE; else if (!str_prefix(argument, "f")) ch->sex = SEX_FEMALE; else if (!str_prefix(argument, "h")) ch->sex = SEX_HERMAPH; else if (!str_prefix(argument, "n")) ch->sex = SEX_NEUTRAL; else { i = number_range(0,100); if (i == 0) ch->sex = SEX_NEUTRAL; else if (i == 100) ch->sex = SEX_HERMAPH; else if (i < 50) ch->sex = SEX_MALE; else ch->sex = SEX_FEMALE; } send_to_char("Your gender has been chosen.\n\r", ch); add_char(ch); ch->desc->connected = CON_PLAYING; return; } void choose_species(CHAR_DATA *ch, char *argument) { char buf[MAX_STRING_LENGTH]; SPECIES_DATA *species; NATION_DATA *nation; int i, n; if (!str_cmp(argument, "races")) { do_races(ch, ""); return; } if (nifty_is_name("races", argument)) { do_races(ch, argument+6); return; } if (nifty_is_name("help", argument)) { do_new_help(ch, argument+5); return; } if (!str_cmp(argument, "random")) { xSET_BIT(ch->act, PLR_FREEZE); if (ch->pcdata->points > 100) ch->pcdata->points = 30; birth(ch); xREMOVE_BIT(ch->act, PLR_FREEZE); if (!xIS_SET(ch->act, PLR_AUTOSEX )) { ch->desc->connected = CON_CHOOSE_SEX; send_to_char("&YChoose your gender [M/F/H/N]\n\r", ch); } else { add_char(ch); ch->desc->connected = CON_PLAYING; } return; } species = find_species(argument); if (!species) { send_to_char("That's not a species.\n\r", ch); send_to_char("What IS your species (or RANDOM if you wish)? ", ch); return; } i = 0; n = 0; for (nation = first_nation;nation;nation = nation->next) { if (!str_cmp(nation->species, species->name)) i++; } i = number_range(1,i); for (nation = first_nation;nation;nation = nation->next) { if (!str_cmp(nation->species, species->name)) n++; if (n == i) { ch->nation = nation; break; } } set_race(ch, TRUE); if (ch->in_room) char_from_room(ch); char_to_room(ch, get_room_index(ROOM_VNUM_NEXUS)); ch_printf(ch, "&WYou are reborn as %s.\n\r", aoran(ch->nation->name)); act(AT_WHITE, "$n is reborn as $T.", ch, NULL, aoran(ch->nation->name), TO_ROOM); do_look(ch, "auto"); sprintf(buf, "%s has been reborn as %s in %s (%d).", ch->name, aoran(ch->nation->name), ch->in_room->name, ch->in_room->vnum); log_string_plus( buf, LOG_COMM, 0 ); if ( IS_SET( sysdata.save_flags, SV_DEATH ) ) save_char_obj(ch); if (!xIS_SET(ch->act, PLR_AUTOSEX )) { ch->desc->connected = CON_CHOOSE_SEX; send_to_char("&YChoose your gender [M/F/H/N]\n\r", ch); } else { add_char(ch); ch->desc->connected = CON_PLAYING; } } void choose_nation(CHAR_DATA *ch, char *argument) { char buf[MAX_STRING_LENGTH]; NATION_DATA *nation; if (!str_cmp("races", argument)) { do_races(ch, ""); return; } if (nifty_is_name("races", argument)) { do_races(ch, argument+6); return; } if (nifty_is_name("help", argument)) { do_new_help(ch, argument+5); return; } if (nifty_is_name("newbie", argument)) { do_chat(ch, argument); return; } if (!str_cmp(argument, "random")) { xSET_BIT(ch->act, PLR_FREEZE); if (ch->pcdata->points > 100) ch->pcdata->points = 30; birth(ch); xREMOVE_BIT(ch->act, PLR_FREEZE); if (!xIS_SET(ch->act, PLR_AUTOSEX )) { ch->desc->connected = CON_CHOOSE_SEX; send_to_char("&YChoose your gender [M/F/H/N]\n\r", ch); } else { add_char(ch); ch->desc->connected = CON_PLAYING; } return; } nation = find_nation(argument); if (!nation) { send_to_char("That's not a nation.\n\r", ch); send_to_char("What IS your nation (or RANDOM if you wish)? ", ch); return; } ch->nation = nation; set_race(ch, TRUE); if (ch->in_room) char_from_room(ch); char_to_room(ch, get_room_index(ROOM_VNUM_NEXUS)); if (IS_NEWBIE(ch)) { ch_printf(ch, "&WYou are born into the Planes as %s.\n\r", aoran(ch->nation->name)); act(AT_WHITE, "$n is born into the Planes as $T.", ch, NULL, aoran(ch->nation->name), TO_ROOM); } else { ch_printf(ch, "&WYou are reborn as %s.\n\r", aoran(ch->nation->name)); act(AT_WHITE, "$n is reborn as $T.", ch, NULL, aoran(ch->nation->name), TO_ROOM); } do_look(ch, "auto"); sprintf(buf, "%s has been reborn as %s in %s (%d).", ch->name, aoran(ch->nation->name), ch->in_room->name, ch->in_room->vnum); log_string_plus( buf, LOG_COMM, 0 ); if ( IS_SET( sysdata.save_flags, SV_DEATH ) ) save_char_obj(ch); if (!xIS_SET(ch->act, PLR_AUTOSEX )) { ch->desc->connected = CON_CHOOSE_SEX; send_to_char("&YChoose your gender [M/F/H/N]\n\r", ch); } else { add_char(ch); ch->desc->connected = CON_PLAYING; } } void newbie_death(CHAR_DATA *ch) { CHAR_DATA *wizard; char buf[MAX_STRING_LENGTH]; PART_DATA *part; send_to_char("You fall unconscious, blackness as the thickest Void encompassing you.\n\r", ch); /* Repair any injuries */ part = ch->first_part; while (part) { part->cond = PART_WELL; part->flags = PART_WELL; part = part->next; } ch->hit = ch->max_hit; ch->mana = ch->max_mana; ch->move = ch->max_move; send_to_char("But after a time, slowly you wake, exhausted and weary, in the Nexus.\n\r", ch); ch->position = POS_RESTING; if (ch->in_room) char_from_room(ch); char_to_room(ch, get_room_index(ROOM_VNUM_NEXUS)); act(AT_MAGIC, "$n appears unconscious from a cloud of mist.", ch, NULL, NULL, TO_ROOM); act(AT_ACTION, "$n stirs slowly, $s eyes blinking open.", ch, NULL, NULL, TO_ROOM); for (wizard = ch->in_room->first_person;wizard;wizard = wizard->next_in_room) { if (nifty_is_name("wizard", wizard->name)) break; } if (wizard) { sprintf(buf, "That was a close one, %s! You should be more careful.", ch->name); do_say(wizard, buf); } ch->mental_state = 0; fix_char(ch); update_aris(ch); STRFREE(ch->last_taken); ch->last_taken = STRALLOC("disoriented from nearly dying"); WAIT_STATE(ch, PULSE_VIOLENCE*2); } void birth(CHAR_DATA *ch) { int i, n, tal; int power; AREA_DATA *area; GENERIC_MOB *race; SPECIES_DATA *species; ROOM_INDEX_DATA *pRoomIndex; char buf[MAX_STRING_LENGTH]; DEITY_DATA *talent; PART_DATA *part; EXPLORED_AREA *xarea; if (IS_NEWBIE(ch) && IS_SET(ch->pcdata->flags, PCFLAG_HELPSTART)) { newbie_death(ch); return; } act(AT_DGREY, "You are drawn into the Void!", ch, NULL, NULL, TO_CHAR); act(AT_DGREY, "$n is drawn into the Void!", ch, NULL, NULL, TO_ROOM); while (ch->first_affect) affect_remove( ch, ch->first_affect ); /* Strip any affects */ STRFREE(ch->pcdata->type); ch->pcdata->type = STRALLOC("living"); REMOVE_BIT(ch->pcdata->flags, PCFLAG_MASK); xREMOVE_BIT(ch->act, PLR_WIZINVIS); REMOVE_BIT(ch->pcdata->flags, PCFLAG_SHIELD); REMOVE_BIT(ch->pcdata->flags, PCFLAG_VAMPIRE); xCLEAR_BITS(ch->pcdata->perm_aff); send_to_char("Your soul shoots through the Void at a dizzying speed,\n\r", ch); /* Repair any injuries */ part = ch->first_part; while (part) { part->cond = PART_WELL; part->flags = PART_WELL; part = part->next; } send_to_char("but time and space have no meaning here.\n\r", ch); /* Forget a random area */ if (!xIS_SET(ch->act, PLR_FREEZE)) { n = 0; for (xarea = ch->pcdata->first_explored;xarea;xarea = xarea->next) { n++; } i = number_range(1, n); n = 0; for (xarea = ch->pcdata->first_explored;xarea;xarea = xarea->next) { n++; if (i == n) { UNLINK(xarea, ch->pcdata->first_explored, ch->pcdata->last_explored, next, prev); DISPOSE(xarea); send_to_char("Within the Void, your memories of your previous lives fade.\n\r", ch); break; } } } /* Screw with their talents */ if ((IS_SET(ch->pcdata->flags, PCFLAG_HELPSTART) && !xIS_SET(ch->act, PLR_FREEZE)) || (!IS_SET(ch->pcdata->flags, PCFLAG_HELPSTART) && xIS_SET(ch->act, PLR_FREEZE))) { if (ch->pcdata->inborn == -1) { ch->pcdata->inborn = number_range(0,18); ch->talent[ch->pcdata->inborn] = number_range(50,150); ch->talent[number_range(0,18)] += number_range(10,50); } n = 0; tal = -1; power = 0; for (talent = first_deity; talent; talent = talent->next) { i = talent->index; if (ch->curr_talent[i] <= 10) ch->talent[i] -= number_range(1,3); if (ch->talent[i] < 20 && ch->curr_talent[i] >= 20) ch->talent[i] += number_range(1,3); if (ch->curr_talent[i] >= 50 && (ch->talent[i] < 100)) ch->talent[i] += number_range(1,3); if (ch->curr_talent[i] >= 100 && (ch->talent[i] < 150)) ch->talent[i] += number_range(1,3); if (ch->curr_talent[i] >= 150 && (ch->talent[i] < 200)) ch->talent[i] += number_range(1,3); if (ch->curr_talent[i] >= 200) ch->talent[i] += number_range(1,3); ch->talent[i] += number_range(-2,2); ch->curr_talent[i] -= number_range(2,6); if (ch->curr_talent[i] < 1) ch->curr_talent[i] = 1; if (ch->talent[i] < 1) ch->talent[i] = 1; if (ch->talent[i] > n) { n = ch->talent[i]; tal = i; } power += ch->talent[i] * talent->cost; } ch->pcdata->inborn = tal; send_to_char("Magic shifts within you as strands of the Talent Pool cling and pull at you.\n\r", ch); } if ( get_timer( ch, TIMER_PKILLED ) > 0 ) remove_timer( ch, TIMER_PKILLED ); ch->hit = ch->max_hit; ch->mana = ch->max_mana; ch->move = ch->max_move; ch->exp = 0; ch->mental_state = 0; ch->pcdata->condition[COND_DRUNK] = 0; ch->speed = 90; send_to_char("Before you lies the expanse of the universe, a thousand paths in every direction...\n\r", ch); /* Choose your destiny */ if (!xIS_SET(ch->act, PLR_FREEZE)) { if (IS_NEWBIE(ch) || power > number_range(50,200)) { send_to_char("&BYou may choose your destiny...\n\r", ch); if (IS_NEWBIE(ch) || power > number_range(500,3000)) { if (IS_SET(ch->pcdata->flags, PCFLAG_HELPSTART)) UNLINK( ch, first_char, last_char, next, prev ); ch->desc->connected = CON_CHOOSE_NATION; send_to_char("&BAll paths are open to you. Choose a nation, or RANDOM if you wish.\n\r", ch); send_to_char("&BType RACES or RACES <species> for a list, and HELP <race> for information.\n\r", ch); return; } else if (power > number_range(200,1000)) { UNLINK( ch, first_char, last_char, next, prev ); ch->desc->connected = CON_CHOOSE_SPECIES; send_to_char("\n\rYou may choose from the following species:\n\r", ch); buf[0] = '\0'; species = first_species; while (species) { if ((strlen(buf) + strlen(species->name)) > 75) { strcat( buf, "\n\r" ); send_to_char(buf, ch); buf[0] = '\0'; } else strcat( buf, " | " ); strcat(buf, species->name); species=species->next; } strcat( buf, " |\n\r " ); send_to_char(buf, ch); return; } else { if (!xIS_SET(ch->act, PLR_AUTOSEX)) { UNLINK( ch, first_char, last_char, next, prev ); ch->desc->connected = CON_CHOOSE_SEX; send_to_char("&YChoose your gender [M/F/H/N]\n\r", ch); } } } else { i = number_range(0,100); if (i == 0) ch->sex = SEX_NEUTRAL; else if (i == 100) ch->sex = SEX_HERMAPH; else if (i < 50) ch->sex = SEX_MALE; else ch->sex = SEX_FEMALE; } } /* Pick a random race by area. * Loop until successful. * Make damn sure you have at least one area with mobs in it, * or this will freeze up. */ send_to_char("One path draws you along, spinning wildly out of your control.\n\r", ch); while (1) { i = number_range(0, last_area->low_soft_range); for (area = first_area;area;area = area->next) { if (area->low_soft_range != i) continue; i = 0; for (race = area->first_race;race;race = race->next) i++; i = number_range(1, i); n = 0; for (race = area->first_race;race;race = race->next) { n++; if (n == i) { if (xIS_SET(race->nation->affected, AFF_UNDEAD)) continue; ch->nation = race->nation; set_race(ch, TRUE); /* Now put them in the area */ for (i = 0;i < 100;i++) { n = number_range(area->low_r_vnum, area->hi_r_vnum); if ((pRoomIndex = get_room_index(n)) == NULL) continue; if (IS_SET(pRoomIndex->room_flags, ROOM_NOFLOOR)) { if (IS_SET(ch->xflags, PART_WINGS)) { xSET_BIT(ch->pcdata->perm_aff, AFF_FLYING); } else continue; } if (!IS_AFFECTED(ch, AFF_AQUA_BREATH) && !IS_AFFECTED(ch, AFF_AQUATIC) && pRoomIndex->curr_water > 20) continue; if (IS_AFFECTED(ch, AFF_AQUATIC) && !IS_AFFECTED(ch, AFF_AQUA_BREATH) && pRoomIndex->curr_water < 20) continue; if (ch->in_room) char_from_room(ch); char_to_room(ch, pRoomIndex); } ch_printf(ch, "You enter the unborn body of %s child.\n\r", aoran(ch->nation->name)); act(AT_WHITE, "$n is reborn as $T.", ch, NULL, aoran(ch->nation->name), TO_ROOM); do_look(ch, "auto"); sprintf(buf, "%s has been reborn as %s in %s (%d).", ch->name, aoran(ch->nation->name), ch->in_room->name, ch->in_room->vnum); log_string_plus( buf, LOG_COMM, 0 ); if ( IS_SET( sysdata.save_flags, SV_DEATH ) ) save_char_obj(ch); send_to_char("As you are born and grow, your life begins anew.\n\r", ch); return; } } } } } void ghost(CHAR_DATA *ch) { if (IS_NEWBIE(ch)) { newbie_death(ch); return; } if (IS_AFFECTED(ch, AFF_ETHEREAL)) { birth(ch); return; } STRFREE(ch->last_taken); ch->last_taken = STRALLOC("disoriented from dying"); WAIT_STATE(ch, PULSE_VIOLENCE*2); act(AT_GREY, "You drift out of your body as a ghost.", ch, NULL, NULL, TO_CHAR); act(AT_GREY, "$n drifts out of $s body as a ghost.", ch, NULL, NULL, TO_ROOM); ch->exp = 0; ch->hit = ch->max_hit; ch->mana = ch->max_mana; ch->move = ch->max_move; ch->position = POS_STANDING; add_timer( ch, TIMER_PKILLED, 100, NULL, 0 ); STRFREE(ch->pcdata->type); ch->pcdata->type = STRALLOC("ghost"); xSET_BIT(ch->pcdata->perm_aff, AFF_ETHEREAL); xSET_BIT(ch->pcdata->perm_aff, AFF_UNDEAD); xSET_BIT(ch->pcdata->perm_aff, AFF_NONLIVING); xSET_BIT(ch->pcdata->perm_aff, AFF_NO_CORPSE); if ( IS_SET( sysdata.save_flags, SV_DEATH ) ) save_char_obj(ch); extract_char(ch, FALSE); } void do_rebirth(CHAR_DATA *ch, char *argument) { if (!IS_AFFECTED(ch, AFF_ETHEREAL)) { send_to_char("It isn't so easy entering the Void when you are in a physical form.\n\r", ch); return; } send_to_char("You release your hold on the physical world, and allow the Void to take you.\n\r", ch); birth(ch); } bool check_rebirth(CHAR_DATA *ch, int i) { if (!ch->desc || !ch->desc->connected == CON_PLAYING) return FALSE; if (!IS_AFFECTED(ch, AFF_ETHEREAL)) i -= 1000; if (!IS_AFFECTED(ch, AFF_UNDEAD)) i -= 1000; if (IS_AFFECTED(ch, AFF_MAGICAL)) i -= 500; if (IS_AFFECTED(ch, AFF_VOID)) i += 1500; if (IS_AFFECTED(ch, AFF_DREAMWORLD)) i += 500; i += number_range(-500,200); i -= TALENT(ch, TAL_DEATH); i -= TALENT(ch, TAL_VOID); if (i > 0) { birth(ch); return TRUE; } else if (i > -100) send_to_char("You feel the Void pulling strongly at your soul.\n\r", ch); else if (i > -300) send_to_char("You are aware of the Void drawing at your soul.\n\r", ch); else if (i > -500) send_to_char("You sense the Void tugging faintly at your soul.\n\r", ch); return FALSE; }