void skill_editor(Client *conn, const char *argument) { char arg[100]; argument = one_argument(argument, arg); if (!str_cmp(arg, "Q")) { finish_editing(conn); return; } if (!str_prefix(arg, "show")) { conn->editing->show(conn); return; } Skill *skill = (Skill *) conn->editing->data; if (!str_cmp(arg, "save")) { save_skill(skill); xwriteln(conn, "~CSkill saved.~x"); return; } if (!str_cmp(arg, "list")) { skill_edit_list(conn); return; } if (!str_cmp(arg, "A") || !str_cmp(arg, "name")) { if (nullstr(argument)) { xwriteln(conn, "~CChange skill name to what?~x"); return; } free_str(skill->name); skill->name = str_dup(argument); conn->editing->show(conn); return; } if (!str_cmp(arg, "B") || !str_cmp(arg, "damage")) { if (nullstr(argument)) { free_str(skill->damage); skill->damage = str_empty; } else { free_str(skill->name); skill->damage = str_dup(argument); } conn->editing->show(conn); return; } if (!str_cmp(arg, "C") || !str_cmp(arg, "msgOff")) { if (nullstr(argument)) { free_str(skill->msgOff); skill->msgOff = str_empty; } else { free_str(skill->msgOff); skill->msgOff = str_dup(argument); } conn->editing->show(conn); return; } if (!str_cmp(arg, "D") || !str_cmp(arg, "msgObj")) { if (nullstr(argument)) { free_str(skill->msgObj); skill->msgObj = str_empty; } else { free_str(skill->msgObj); skill->msgObj = str_dup(argument); } conn->editing->show(conn); return; } if (!str_cmp(arg, "F") || !str_cmp(arg, "mana")) { if (!is_number(argument)) { xwriteln(conn, "~CThat is not a number.~x"); return; } skill->mana = atoi(argument); conn->editing->show(conn); } if (!str_cmp(arg, "E") || !str_cmp(arg, "wait")) { if (!is_number(argument)) { xwriteln(conn, "~CThat is not a number.~x"); return; } skill->mana = atoi(argument); conn->editing->show(conn); return; } if (!str_cmp(arg, "G") || !str_cmp(arg, "cost")) { if (!is_number(argument)) { xwriteln(conn, "~CThat is not a number.~x"); return; } skill->mana = (float) atof(argument); conn->editing->show(conn); return; } if (!str_cmp(arg, "H") || !str_cmp(arg, "spell")) { if (nullstr(argument)) { skill->spellfun = 0; } else { skill->spellfun = spellfun_lookup(argument); if (skill->spellfun == 0) { xwriteln(conn, "~CValid spells are:~x"); int i; for (i = 0; spellfun_table[i].name != 0; i++) { xwritef(conn, "%-10s ", spellfun_table[i].name); if (i % 4 == 0) { xwriteln(conn, ""); } } if (i % 4 != 0) { xwriteln(conn, ""); } return; } } conn->editing->show(conn); return; } if (!str_cmp(arg, "I") || !str_cmp(arg, "gsn")) { if (nullstr(argument)) { skill->pgsn = 0; conn->editing->show(conn); return; } skill->pgsn = gsn_lookup(argument); if (skill->pgsn == 0) { xwriteln(conn, "~CValid gsns are:~x"); int i; for (i = 0; gsn_table[i].name != 0; i++) { xwritef(conn, "%-10s ", gsn_table[i].name); if (i % 4 == 0) { xwriteln(conn, ""); } } if (i % 4 != 0) { xwriteln(conn, ""); } return; } conn->editing->show(conn); return; } if (!str_cmp(arg, "J") || !str_cmp(arg, "minpos")) { long pos = value_lookup(position_table, argument); if (pos == -1) { xwritelnf(conn, "~CValid positions are: ~W%s~x", lookup_names(position_table)); return; } skill->minPos = (position_t) pos; conn->editing->show(conn); return; } if (!str_cmp(arg, "K") || !str_cmp(arg, "flags")) { if (edit_flag ("flags", conn, &skill->flags, argument, skill_flags)) { conn->editing->show(conn); } return; } if (!str_cmp(arg, "L") || !str_cmp(arg, "levels")) { char name[BUF_SIZ]; argument = one_argument(argument, name); int c = class_lookup(name); if (c == -1) { xwriteln(conn, "~CValid classes are:~W"); for (int i = 0; i < max_class; i++) { xwritef(conn, "%s ", class_table[i].name); } xwriteln(conn, "~x"); return; } if (!is_number(argument)) { xwriteln(conn, "~CThat is not a valid level.~x"); return; } skill->levels[c] = atoi(argument); conn->editing->show(conn); return; } }
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); }
/* * New code for loading clans from file. */ bool fread_clan( CLAN_DATA *clan, FILE *fp ) { const char *word; bool fMatch; int stat; for ( ; ; ) { GET_TOKEN( fp, word, "End" ); fMatch = FALSE; switch ( UPPER( word[0] ) ) { case '*': fMatch = TRUE; fread_to_eol( fp ); break; case 'C': SKEY( "Chieftain", clan->chieftain ); if ( !str_cmp( word, "Class" ) ) { clan->cclass = class_lookup( temp_fread_string( fp, &stat ) ); fMatch = TRUE; break; } KEY( "ClanHeros", clan->clanheros, fread_number( fp, &stat ) ); KEY( "ClanType", clan->clan_type, fread_number( fp, &stat ) ); KEY( "ClanObjOne", clan->clanobj1, fread_number( fp, &stat ) ); KEY( "ClanObjTwo", clan->clanobj2, fread_number( fp, &stat ) ); KEY( "ClanObjThree", clan->clanobj3, fread_number( fp, &stat ) ); break; case 'D': SKEY( "Desc", clan->description ); KEY( "Donation", clan->donation, fread_number( fp, &stat ) ); break; case 'E': if ( !str_cmp( word, "End" ) ) return TRUE; break; case 'I': KEY( "IllegalPK", clan->illegal_pk, fread_number( fp, &stat ) ); break; case 'M': KEY( "Members", clan->members, fread_number( fp, &stat ) ); KEY( "MKills", clan->mkills, fread_number( fp, &stat ) ); KEY( "MDeaths", clan->mdeaths, fread_number( fp, &stat ) ); SKEY( "Motto", clan->motto ); break; case 'N': SKEY( "Name", clan->name ); break; case 'O': SKEY( "Overlord", clan->overlord ); break; case 'P': KEY( "PKills", clan->pkills, fread_number( fp, &stat ) ); KEY( "PDeaths", clan->pdeaths, fread_number( fp, &stat ) ); break; case 'R': KEY( "Recall", clan->recall, fread_number( fp, &stat ) ); break; case 'S': KEY( "Score", clan->score, fread_number( fp, &stat ) ); KEY( "Subchiefs", clan->subchiefs, fread_number( fp, &stat ) ); break; case 'W': SKEY( "WhoName", clan->who_name ); break; } if ( !fMatch ) { bugf( "Load_clan_file: no match: %s", word ); } } return FALSE; }
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 ); }