/* Extract a ch completely from the world, and leave his stuff behind */ void extract_char(struct char_data * ch) { struct char_data *k, *temp; struct descriptor_data *t_desc; struct obj_data *obj; int i, freed = 0; //int j; extern struct char_data *combat_list; ACMD(do_return); void die_follower(struct char_data * ch); if (!IS_NPC(ch) && !ch->desc) { for (t_desc = descriptor_list; t_desc; t_desc = t_desc->next) { if (t_desc->original == ch) { do_return(t_desc->character, "", 0, 0); } } } if (ch->in_room == NOWHERE) { log("SYSERR: NOWHERE extracting char. (handler.c, extract_char)"); exit(1); } if (ch->followers || ch->master) { die_follower(ch); } if (RIDING(ch) || RIDDEN_BY(ch)) dismount_char(ch); REMOVE_BIT(PLR_FLAGS(ch), PLR_FISHING); REMOVE_BIT(PLR_FLAGS(ch), PLR_FISH_ON); REMOVE_BIT(PLR_FLAGS(ch), PLR_DIGGING); REMOVE_BIT(PLR_FLAGS(ch), PLR_DIG_ON); REMOVE_BIT(PLR_FLAGS(ch), PLR_FIRE_ON); REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF); //REMOVE_BIT(PRF_FLAGS(ch), PRF_DISGUISE); //REMOVE_BIT(PLR_FLAGS(ch), PLR_MAGE); //REMOVE_BIT(PLR_FLAGS(ch), PLR_MONK); //REMOVE_BIT(PLR_FLAGS(ch), PLR_KNIGHT); //REMOVE_BIT(PLR_FLAGS(ch), PLR_CLERIC); //REMOVE_BIT(PLR_FLAGS(ch), PLR_BARD); //REMOVE_BIT(PLR_FLAGS(ch), PLR_BEGGAR); REMOVE_BIT(PLR_FLAGS(ch), PLR_COURIER); REMOVE_BIT(PLR_FLAGS(ch), PLR_BEAR); REMOVE_BIT(PLR_FLAGS(ch), PLR_BIRD); REMOVE_BIT(PLR_FLAGS(ch), PLR_WOLF); REMOVE_BIT(PLR_FLAGS(ch), PLR_RABBIT); REMOVE_BIT(PLR_FLAGS(ch), PLR_CAT); /* Forget snooping, if applicable */ if (ch->desc) { if (ch->desc->snooping) { ch->desc->snooping->snoop_by = NULL; ch->desc->snooping = NULL; } if (ch->desc->snoop_by) { SEND_TO_Q("Your victim is no longer among us.\r\n", ch->desc->snoop_by); ch->desc->snoop_by->snooping = NULL; ch->desc->snoop_by = NULL; } } /* transfer objects to room, if any */ while (ch->carrying) { obj = ch->carrying; obj_from_char(obj); obj_to_room(obj, ch->in_room); } /* transfer equipment to room, if any */ for (i = 0; i < NUM_WEARS; i++) { if (GET_EQ(ch, i)) { obj_to_room(unequip_char(ch, i), ch->in_room); } } if (FIGHTING(ch)) { stop_fighting(ch); } for (k = combat_list; k; k = temp) { temp = k->next_fighting; if (FIGHTING(k) == ch) { stop_fighting(k); } } char_from_room(ch); /* pull the char from the list */ REMOVE_FROM_LIST(ch, character_list, next); if (ch->desc && ch->desc->original) { do_return(ch, NULL, 0, 0); } if (!IS_NPC(ch)) { save_char(ch, NOWHERE); Crash_delete_crashfile(ch); } else { if (GET_MOB_RNUM(ch) > -1) { /* if mobile */ mob_index[GET_MOB_RNUM(ch)].number--; } clearMemory(ch); /* Only NPC's can have memory */ if (SCRIPT(ch)) { extract_script(SCRIPT(ch)); } free_char(ch); freed = 1; } if (!freed && ch->desc != NULL) { STATE(ch->desc) = CON_MENU; SEND_TO_Q(MENU, ch->desc); } else { /* if a player gets purged from within the game */ if (ch->master || ch->followers) die_follower(ch); if (!freed) { free_char(ch); } } }
/* Extract a ch completely from the world, and leave his stuff behind */ void extract_char_smarter(struct char_data *ch, int save_room) { struct obj_data *i; struct char_data *k, *next_char; struct descriptor_data *t_desc; int l, was_in, j; extern long mob_count; extern struct char_data *combat_list; void do_save(struct char_data *ch, char *argument, int cmd); void do_return(struct char_data *ch, char *argument, int cmd); void die_follower(struct char_data *ch); if(IS_SET(ch->specials.act, ACT_FIGURINE) && ch->link) extract_obj(ch->link); if(!IS_NPC(ch) && !ch->desc) { for(t_desc = descriptor_list; t_desc; t_desc = t_desc->next) if(t_desc->original==ch) do_return(t_desc->character, "", 0); } if (ch->in_room == NOWHERE) { logE("NOWHERE extracting char. (handler.c, extract_char)"); /* ** problem from linkdeath */ char_to_room(ch, 4); /* 4 == all purpose store */ } if (ch->followers || ch->master) die_follower(ch); if(ch->desc) { /* Forget snooping */ if ((ch->desc->snoop.snooping) && (ch->desc->snoop.snooping->desc)) ch->desc->snoop.snooping->desc->snoop.snoop_by = 0; if (ch->desc->snoop.snoop_by) { send_to_char("Your victim is no longer among us.\n\r", ch->desc->snoop.snoop_by); if (ch->desc->snoop.snoop_by->desc) ch->desc->snoop.snoop_by->desc->snoop.snooping = 0; } ch->desc->snoop.snooping = ch->desc->snoop.snoop_by = 0; } if (ch->carrying) { /* transfer ch's objects to room */ if (!IS_IMMORTAL(ch)) { while(ch->carrying) { i=ch->carrying; obj_from_char(i); obj_to_room(i, ch->in_room); check_falling_obj(i, ch->in_room); } } else { send_to_char("Here, you dropped some stuff, let me help you get rid of that.\n\r",ch); /* equipment too */ for (j=0; j<MAX_WEAR; j++) { if (ch->equipment[j]) obj_to_char(unequip_char(ch, j), ch); } while (ch->carrying) { i = ch->carrying; obj_from_char(i); extract_obj(i); } } } if (ch->specials.fighting) stop_fighting(ch); for (k = combat_list; k ; k = next_char) { next_char = k->next_fighting; if (k->specials.fighting == ch) stop_fighting(k); } if (MOUNTED(ch)) { Dismount(ch, MOUNTED(ch), POSITION_STANDING); } if (RIDDEN(ch)) { Dismount(RIDDEN(ch), ch, POSITION_STANDING); } /* Must remove from room before removing the equipment! */ was_in = ch->in_room; char_from_room(ch); /* clear equipment_list */ for (l = 0; l < MAX_WEAR; l++) if (ch->equipment[l]) obj_to_room(unequip_char(ch,l), was_in); if (IS_NPC(ch)) { for (k=character_list; k; k=k->next) { if (k->specials.hunting) if (k->specials.hunting == ch) { k->specials.hunting = 0; } if (Hates(k, ch)) { RemHated(k, ch); } if (Fears(k, ch)) { RemFeared(k, ch); } if (k->orig == ch) { k->orig = 0; } } } else { for (k=character_list; k; k=k->next) { if (k->specials.hunting) if (k->specials.hunting == ch) { k->specials.hunting = 0; } if (Hates(k, ch)) { ZeroHatred(k, ch); } if (Fears(k, ch)) { ZeroFeared(k, ch); } if (k->orig == ch) { k->orig = 0; } } } /* pull the char from the list */ if (ch == character_list) character_list = ch->next; else { for(k = character_list; (k) && (k->next != ch); k = k->next); if(k) k->next = ch->next; else { logE("Trying to remove ?? from character_list.(handler.c,extract_char)"); exit(0); } } if (ch->specials.gname) free(ch->specials.gname); GET_AC(ch) = 100; if (ch->desc) { if (ch->desc->original) do_return(ch, "", 0); if (!strcmp(GET_NAME(ch), "Odin's heroic minion")) { free(GET_NAME(ch)); GET_NAME(ch) = strdup("111111"); } save_char(ch, save_room); } t_desc = ch->desc; if(ch->term) { ScreenOff(ch); ch->term = 0; } if (IS_NPC(ch)) { if (ch->nr > -1) /* if mobile */ mob_index[ch->nr].number--; FreeHates(ch); FreeFears(ch); mob_count--; free_char(ch); } if (t_desc) { t_desc->connected = CON_SLCT; SEND_TO_Q(MENU, t_desc); } }
void do_multiclass(CHAR_DATA *ch, const char *argument) { int iClass; // char arg[MAX_INPUT_LENGTH]; ROOM_INDEX_DATA *pRoom; OBJ_DATA *obj; if (IS_NPC(ch)){ send_to_char("Mobs can't multiclass!\n\r",ch); return; } if (IS_IMMORTAL(ch)) { send_to_char("Immortals are damned to be immortals.\n\r",ch); return; } // argument = one_argument(argument,arg); if (argument[0] == 0) { send_to_char("You must provide a class name to add to your class list.\n\r",ch); return; } iClass = class_lookup(argument, TRUE ); if (iClass == -1) { send_to_char("You must provide an existing class name to add to your class list.\n\r",ch); return; } if ((1<<iClass) & ch->bstat(classes)) { send_to_char("Choose a class that you don't already have.\n\r",ch); return; } // Added by SinaC 2001 if ( !check_class_god( iClass, ch->pcdata->god ) ){ send_to_charf(ch, "%s doesn't allow that class.\n\r", god_name(ch->pcdata->god)); return; } if ( !check_class_race( ch, iClass ) ){ send_to_char( "You can't choose that class because of your race.\n\r", ch ); return; } // Added by SinaC 2003 for subclass system // If trying to multiclass in a subclass without having the parent class // Should be able to get only one sub-class for each parent-class // Cannot be fire and water elementalist // Cannot be enchanter and transmuter // But can be assassin and fire elementalist if ( class_table[iClass].parent_class != iClass && !((1<<class_table[iClass].parent_class) & ch->bstat(classes))) { send_to_char("You can't choose this sub-class because you don't have the parent class.\n\r", ch ); return; } // Added by SinaC 2003 to determine if a class can be picked during creation/multiclass if ( class_table[iClass].choosable != CLASS_CHOOSABLE_YES ) { send_to_char("This class cannot be picked.\n\r", ch ); return; } // check wild-magic if ( ch->isWildMagic // can't get non-wild magic class && IS_SET( class_table[iClass].type, CLASS_MAGIC ) // if wild mage && !IS_SET( class_table[iClass].type, CLASS_WILDABLE ) ) { send_to_charf(ch,"This class cannot be picked by a wild-mage.\n\r"); return; } // kill pet and charmies die_follower( ch ); /* Test if fighting ? */ stop_fighting( ch, TRUE ); /* Go to donation room */ pRoom = get_donation_room( ch ); //pRoom = get_room_index( ROOM_VNUM_DONATION ); if (pRoom==NULL) { bug("do_multiclass: donation room not found for player [%s] clan [%s] hometown [%s]!", NAME(ch), get_clan_table(ch->clan)->name, (IS_NPC(ch)||ch->pcdata->hometown<0)?"none":hometown_table[ch->pcdata->hometown].name); //bug("multiclass: donation room not found %d!",ROOM_VNUM_DONATION); return; } if (ch->in_room != pRoom) { act("$n disapears!",ch,NULL,NULL,TO_ROOM); char_from_room( ch ); char_to_room( ch, pRoom ); act( "$n appears in the donation room.", ch, NULL, NULL, TO_ROOM ); } ch->level = 1; ch->bstat(classes) |= 1<<iClass; ch->hit = 20; /* I should place constants instead of "hard code" */ ch->bstat(max_hit) = 20; ch->mana = 100; ch->bstat(max_mana) = 100; // Added by SinaC 2001 for mental user ch->psp = 100; ch->bstat(max_psp) = 100; ch->move = 100; ch->bstat(max_move) = 100; ch->wimpy = 0; /* ch->pcdata->points = ? creation points*/ ch->exp = exp_per_level(ch,ch->pcdata->points); /* Train - Pra ?*/ /* Gain base group*/ group_add(ch,class_table[iClass].base_group,FALSE); /*group_add(ch,class_table[iClass].default_group,TRUE);*/ /* adding this would raise creation points too much*/ /*group_add(ch,class_table[iClass].default_group,FALSE);*/ /* adding this would be too easy for the player */ /* gold & silver ?*/ /* Dealing with equipment */ // FIXME: item STAY_DEATH or owned equipement must be dropped ? while ( ch->carrying != NULL ) { /* Remove the obj if it is worn */ obj = ch->carrying; if (obj->wear_loc != WEAR_NONE) unequip_char( ch, obj ); obj_from_char( obj ); obj_to_room( obj, pRoom ); SET_OBJ_STAT( obj, ITEM_DONATED); } // Added by SinaC 2001 recompute(ch); // Added by SinaC 2001 recomproom(pRoom); do_outfit(ch,""); send_to_char("You are now mortal again...\n\r",ch); send_to_char("You see all your possesions lying on the ground...\n\r",ch); send_to_char("Probably few things are still usable, you'd better\n\r" "leave them here.\n\r",ch); char buf[MAX_INPUT_LENGTH]; sprintf( buf, "$N has multiclassed in %s.", class_table[iClass].name ); wiznet(buf, ch, NULL, WIZ_MULTICLASS, 0, 0 ); }
/* Extract a ch completely from the world, and leave his stuff behind */ void extract_char_final(struct char_data *ch) { struct char_data *k, *temp; struct descriptor_data *d; struct obj_data *obj; int i; if (IN_ROOM(ch) == NOWHERE) { log("SYSERR: NOWHERE extracting char %s. (%s, extract_char_final)", GET_NAME(ch), __FILE__); exit(1); } /* We're booting the character of someone who has switched so first we need * to stuff them back into their own body. This will set ch->desc we're * checking below this loop to the proper value. */ if (!IS_NPC(ch) && !ch->desc) { for (d = descriptor_list; d; d = d->next) if (d->original == ch) { do_return(d->character, NULL, 0, 0); break; } } if (ch->desc) { /* This time we're extracting the body someone has switched into (not the * body of someone switching as above) so we need to put the switcher back * to their own body. If this body is not possessed, the owner won't have a * body after the removal so dump them to the main menu. */ if (ch->desc->original) do_return(ch, NULL, 0, 0); else { /* Now we boot anybody trying to log in with the same character, to help * guard against duping. CON_DISCONNECT is used to close a descriptor * without extracting the d->character associated with it, for being * link-dead, so we want CON_CLOSE to clean everything up. If we're * here, we know it's a player so no IS_NPC check required. */ for (d = descriptor_list; d; d = d->next) { if (d == ch->desc) continue; if (d->character && GET_IDNUM(ch) == GET_IDNUM(d->character)) STATE(d) = CON_CLOSE; } STATE(ch->desc) = CON_MENU; write_to_output(ch->desc, "%s", CONFIG_MENU); } } /* On with the character's assets... */ if (ch->followers || ch->master) die_follower(ch); /* Check to see if we are grouped! */ if (GROUP(ch)) leave_group(ch); /* transfer objects to room, if any */ while (ch->carrying) { obj = ch->carrying; obj_from_char(obj); obj_to_room(obj, IN_ROOM(ch)); } /* transfer equipment to room, if any */ for (i = 0; i < NUM_WEARS; i++) if (GET_EQ(ch, i)) obj_to_room(unequip_char(ch, i), IN_ROOM(ch)); if (FIGHTING(ch)) stop_fighting(ch); for (k = combat_list; k; k = temp) { temp = k->next_fighting; if (FIGHTING(k) == ch) stop_fighting(k); } /* Whipe character from the memory of hunters and other intelligent NPCs... */ for (temp = character_list; temp; temp = temp->next) { /* PCs can't use MEMORY, and don't use HUNTING() */ if (!IS_NPC(temp)) continue; /* If "temp" is hunting our extracted char, stop the hunt. */ if (HUNTING(temp) == ch) HUNTING(temp) = NULL; /* If "temp" has allocated memory data and our ch is a PC, forget the * extracted character (if he/she is remembered) */ if (!IS_NPC(ch) && GET_POS(ch) == POS_DEAD && MEMORY(temp)) forget(temp, ch); /* forget() is safe to use without a check. */ } char_from_room(ch); if (IS_NPC(ch)) { if (GET_MOB_RNUM(ch) != NOTHING) /* prototyped */ mob_index[GET_MOB_RNUM(ch)].number--; clearMemory(ch); if (SCRIPT(ch)) extract_script(ch, MOB_TRIGGER); if (SCRIPT_MEM(ch)) extract_script_mem(SCRIPT_MEM(ch)); } else { save_char(ch); Crash_delete_crashfile(ch); } /* If there's a descriptor, they're in the menu now. */ if (IS_NPC(ch) || !ch->desc) free_char(ch); }
/* Extract a ch completely from the world, and leave his stuff behind */ void extract_char(struct char_data *ch, bool pull) { struct obj_data *obj; struct char_data *k, *next_char; struct descriptor_data *t_desc; int l, was_in; extern struct char_data *combat_list; void die_follower(struct char_data *ch); if ( !IS_NPC(ch) && !ch->desc ) { for ( t_desc = descriptor_list; t_desc; t_desc = t_desc->next ) { if ( t_desc->original == ch ) do_return( t_desc->character, "", 0 ); } } if ( ch->in_room == NOWHERE ) { log( "Extract_char: NOWHERE" ); exit( 1 ); } if ( ch->followers || ch->master ) die_follower(ch); while ( ( obj = ch->carrying ) != NULL ) { obj_from_char( obj ); obj_to_room( obj, ch->in_room ); } if ( ch->specials.fighting ) stop_fighting( ch ); for ( k = combat_list; k ; k = next_char ) { next_char = k->next_fighting; if ( k->specials.fighting == ch ) stop_fighting( k ); } /* Must remove from room before removing the equipment! */ was_in = ch->in_room; char_from_room( ch ); if ( !pull ) char_to_room(ch, real_room(3001)); /* clear equipment_list */ for ( l = 0; l < MAX_WEAR; l++ ) { if ( ch->equipment[l] ) obj_to_room(unequip_char(ch,l), was_in); } GET_AC(ch) = 100; if ( ch->desc && ch->desc->original ) do_return( ch, "", 0 ); if ( IS_NPC(ch) && ch->nr > -1 ) mob_index[ch->nr].number--; if ( pull ) { if ( ch == character_list ) character_list = ch->next; else { for ( k = character_list; k && k->next != ch; k = k->next ) ; if ( k ) k->next = ch->next; else { log( "Extract_char: bad char list" ); abort(); } } free_char( ch ); } }