Beispiel #1
0
void do_specialize( CHAR_DATA *ch, const char *argument ) {
  int iClass, iWeapon;
  //  char arg[MAX_INPUT_LENGTH];

  if (IS_NPC(ch)){
    send_to_char("Mobs can't specialize!\n\r",ch);
    return;
  }

  // find a practicer
  CHAR_DATA *practicer;
  for ( practicer = ch->in_room->people; practicer != NULL; practicer = practicer->next_in_room)
    if (IS_NPC(practicer) && IS_SET(practicer->act,ACT_PRACTICE))
      break;
  
  if (practicer == NULL || !can_see(ch,practicer)) {
    send_to_char("You can't do that here.\n\r",ch);
    return;
  }

  //  argument = one_argument(argument,arg);

  // No arg
  if (argument[0] == 0) {
    Value *v = get_extra_field( ch, "specialized_weapon" );
    if ( v != NULL ) { // extra field found
      int specialized = v->asInt();
      send_to_charf(ch, "You are specialized in %s.\n\r", flag_string(weapon_class,specialized));
    }
    else
      specialize_syntax( ch );
  }
  // List available classes
  else if ( !str_cmp( argument, "list" ) ) {
    bool found = FALSE;
    char buf[MAX_STRING_LENGTH];
    char buf2[MAX_STRING_LENGTH];
    buf[0] = '\0';
    for ( int i = 0; i < MAX_CLASS; i++ ) {
      if ( class_table[i].name == NULL ) continue;
      if ( (1 << i) & ch->bstat(classes) ) continue;                     // already has that class
      if ( class_table[i].parent_class == i ) continue;                  // not a sub-class
      if ( !check_class_god( i, ch->pcdata->god ) ) continue;            // god doesn't like that class
      if ( !check_class_race( ch, i ) ) continue;                        // race can't be that class
      if (class_table[i].parent_class != i                               // doesn't have parent class
	  && !((1<<class_table[i].parent_class) & ch->bstat(classes)) ) continue;
      if ( class_table[i].choosable == CLASS_CHOOSABLE_NEVER ) continue; // can't be picked
      if ( ch->isWildMagic                                               // can't get non-wild magic
	   && IS_SET( class_table[i].type, CLASS_MAGIC )                 //  class if wild mage
	   && !IS_SET( class_table[i].type, CLASS_WILDABLE ) ) continue;

      sprintf(buf2,"  %s\n\r", class_table[i].name );
      strcat(buf,buf2);
      found = TRUE;
    }
    
    if (found) {
      send_to_char("Available classes to specialize in:\n\r",ch);
      send_to_char(buf,ch);
    }
    else
      send_to_char("You can't specialize in a class.\n\r", ch );
  }
  // List weapon available weapon
  else if ( !str_cmp( argument, "weapon" ) ) {
    if ( get_ability( ch, gsn_specialization ) == 0 ) {
      send_to_char("You don't know how to specialize in a weapon type.\n\r", ch );
      return;
    }
    bool found = FALSE;
    char buf[MAX_STRING_LENGTH];
    char buf2[MAX_STRING_LENGTH];
    buf[0] = '\0';
    for (int type = 0; weapon_table[type].name != NULL; type++)
      if ( weapon_table[type].gsn != NULL 
	   && get_ability( ch, *(weapon_table[type].gsn) ) == 100 ) {
	found = TRUE;
	sprintf(buf2,"  %s\n\r", weapon_table[type].name );
	strcat(buf,buf2);
      }
    if ( found ) {
      send_to_char("Available weapons to specialize in:\n\r",ch);
      send_to_char(buf,ch);
    }
    else
      send_to_char("You are not proficient enough in any weapon type.\n\r", ch );
  }
  // Weapon
  else if ( ( iWeapon = weapon_lookup(argument) ) >= 0 ) {
    if ( get_ability( ch, gsn_specialization ) == 0 ) {
      send_to_char("You don't know how to specialize in a weapon type.\n\r", ch );
      return;
    }
    if ( weapon_table[iWeapon].gsn
	 && get_ability( ch, *(weapon_table[iWeapon].gsn) ) != 100 ) {
      send_to_charf(ch,"You are not proficient enough in %s.\n\r", weapon_table[iWeapon].name );
      return;
    }
    Value *sp = get_extra_field( ch, "specialized_weapon" );
    if ( sp != NULL ) {
      int w = sp->asInt();
      send_to_charf(ch,"You already specialized in %s.\n\r", w>=0?weapon_table[w].name:"Unknown" );
      return;
    }
    // Add an extra field storing in which weapon the player is specialized
    Value v = add_extra_field( ch, "specialized_weapon" );
    v.setValue( weapon_table[iWeapon].type );
    send_to_charf(ch,"You are now specialized in %s.\n\r", weapon_table[iWeapon].name );
  }
  // Class
  else if ( ( iClass = class_lookup(argument, TRUE) ) >= 0 ) {
    if ((1<<iClass) & ch->bstat(classes)) {
      send_to_char("Choose a class that you don't already have.\n\r",ch);
      return;
    }
    if ( class_table[iClass].parent_class == iClass ) {
      send_to_char("This is not a sub-class.\n\r", ch );
      return;
    }
    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;
    }
    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_NEVER ) {
      send_to_char("This class cannot be picked.\n\r", ch );
      return;
    }
    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;
    }

    // Remove parent class
    REMOVE_BIT( ch->bstat(classes), 1<<class_table[iClass].parent_class );
    // Add sub-class
    SET_BIT( ch->bstat(classes), 1<<iClass );
    
    send_to_charf(ch,"You specialize yourself as %s.\n\r", class_table[iClass].name );
    recompute(ch);
  }
  else
    specialize_syntax(ch);
}
Beispiel #2
0
static char *
liner_desc_char(int n)
{
  char buf[LEN];
  extern int show_combat_flag;
  char *s;
  int sk;

  strcpy(buf, box_name(n));

  sk = subkind(n);

  if (sk == sub_ni) {
    int mk = noble_item(n);
    int num = has_item(n, mk) + 1;

    if (num == 1)
      strcat(buf, sout(", %s", plural_item_name(mk, num)));
    else
      strcat(buf, sout(", %s, number:~%s",
                       plural_item_name(mk, num), comma_num(num)));
  }
  else if (sk) {
    if (sk == sub_temple) {
      if (is_temple(n)) {
        strcat(buf, sout(", Temple of %s", god_name(is_temple(n))));
      }
      else {
        strcat(buf, sout(", undedicated temple"));
      };
    }
    else if (sk == sub_guild) {
      strcat(buf, sout(", %s Guild", box_name(is_guild(n))));
    }
    else {
      strcat(buf, sout(", %s", subkind_s[sk]));
    };
  }

  strcat(buf, nation_s(n));
  strcat(buf, deserted_s(n));
  strcat(buf, rank_s(n));
  strcat(buf, mage_s(n));
  strcat(buf, priest_s(n));
#if 0
  strcat(buf, wield_s(n));
#endif

  if (show_combat_flag) {
    if (char_behind(n))
      strcat(buf, sout(", behind~%d%s", char_behind(n), combat_ally));
    else
      strcat(buf, combat_ally);
  }
  else if (char_guard(n) && stack_leader(n) == n &&
           subkind(n) != sub_garrison)
    strcat(buf, ", on guard");

#if 0
  if (subkind(n) == 0) {        /* only show lord for regular players */
    int sp = lord(n);

    if (sp != indep_player && !cloak_lord(n))
      strcat(buf, sout(", of~%s", box_code_less(sp)));
  }
#endif

  if (show_display_string) {
    s = banner(n);

    if (s && *s)
      strcat(buf, sout(", \"%s\"", s));
  }

  strcat(buf, with_inventory_string(n));

  if (is_prisoner(n))
    strcat(buf, ", prisoner");

  return sout("%s", buf);
}
Beispiel #3
0
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 );
}