/**************************************************************************/ // olc_ex.cpp - Extended commands for olc - Dawn only code in here :) /*************************************************************************** * The Dawn of Time v1.69r (c)1997-2004 Michael Garratt * * >> A number of people have contributed to the Dawn codebase, with the * * majority of code written by Michael Garratt - www.dawnoftime.org * * >> To use this source code, you must fully comply with the dawn license * * in licenses.txt... In particular, you may not remove this copyright * * notice. * **************************************************************************/ #include "include.h" #include "olc_ex.h" #include "olc.h" #include "help.h" /**************************************************************************/ // Lookup a spell by name - exact match - Kal int spell_exact_lookup( const char *name ) { int sn; for( sn = FIRST_SPELL; sn < LAST_SPELL; sn++ ) { if( IS_NULLSTR(skill_table[sn].name)) break; if( !str_cmp( name, skill_table[sn].name ) ) return sn; } return -1; } /**************************************************************************/ // Lookup a spell by name - Kal int spell_lookup( const char *name ) { int sn; sn=spell_exact_lookup(name); if(sn>-1){ return sn; } for( sn = FIRST_SPELL; sn < LAST_SPELL; sn++ ) { if( IS_NULLSTR(skill_table[sn].name)) break; if( LOWER(name[0]) == LOWER(skill_table[sn].name[0]) && !str_prefix( name, skill_table[sn].name ) ) return sn; } return -1; } /**************************************************************************/ // Returns the name of a skill without crashing if sn is out of bounds - Kal char * safe_skill_name(int sn) { if(sn==-1){ return "unassigned"; } if(sn<-1 || sn>MAX_SKILL-1){ return "unknown!"; } return skill_table[sn].name; } /**************************************************************************/ // return true if changed - Kal bool olc_generic_skill_assignment_to_int(char_data *ch, int *field, const char *argument, bool spell_only, bool extra_lf, const char *command_name, const char *description_of_field_sprintf, ...) { // format the description_of_field_sprintf into description char description[MSL]; va_list args; va_start(args, description_of_field_sprintf); vsnprintf(description, MSL-10, description_of_field_sprintf, args); va_end(args); if(IS_NULLSTR(argument)){ ch->printlnf("`Bsyntax:`x %s <%s> - to change/assign %s to %s", command_name, spell_only?"spell":"skill/spell", spell_only?"spell":"skill/spell", description); ch->printlnf("`Bsyntax:`x %s clear - to clear %s", command_name, description); ch->printlnf("`x%s is currently assigned as: %s`x", capitalize(description), safe_skill_name(*field)); if(extra_lf) ch->println(""); return false; } if(!str_cmp(argument,"clear")){ if(*field==-1){ ch->printlnf("`Y%s is already unassigned!`x", capitalize(description)); if(extra_lf) ch->println(""); return false; } ch->printlnf("`G%s cleared, was originally set to %s.`x", capitalize(description), safe_skill_name(*field)); *field=-1; if(extra_lf) ch->println(""); return true; } int value; if(spell_only){ value=spell_lookup( argument ); }else{ value=skill_lookup( argument ); } if(value==-1){ ch->printlnf("`RNo such %s '`x%s`R' found!`x", spell_only?"spell":"skill/spell", argument); olc_generic_skill_assignment_to_int(ch, field, "", spell_only, extra_lf, command_name, description); return false; } if(*field==value){ ch->printlnf("`Y%s is already assigned to `x%s!", capitalize(description), safe_skill_name(value)); if(extra_lf) ch->println(""); return false; } ch->printlnf( "`G%s changed from `x%s `Gto `x%s.", capitalize(description), safe_skill_name(*field), safe_skill_name(value)); *field= value; if(extra_lf) ch->println(""); return true; } /**************************************************************************/ // turns the list of all flags in a table char *flagtable_names( const struct flag_type *flag_table) { static int i; static char buf[5][512]; int flag; // rotate buffers ++i= i%5; buf[i][0] = '\0'; for(flag = 0; flag_table[flag].name != NULL; flag++){ strcat( buf[i], " " ); strcat( buf[i], flag_table[flag].name ); } return buf[i]+1; } /**************************************************************************/ bool is_stat( const struct flag_type *flag_table ); /**************************************************************************/ // Kal - Jan 2001 void show_olc_flags_types(char_data *ch, const struct flag_type *flag_table) { int count=0; for(int flag = 0; !IS_NULLSTR(flag_table[flag].name); flag++) { if(flag_table[flag].settable){ count++; ch->printf("`=R %-34s`x%s", flag_table[flag].name, count%2==0?"\r\n":""); } } ch->println(""); } /**************************************************************************/ // Kal - Jan 2001 void show_olc_flags_types_value(char_data *ch, const struct flag_type *flag_table, const char *command_name, long value) { int count=0; bool type_table=is_stat(flag_table); char c; for(int flag = 0; !IS_NULLSTR(flag_table[flag].name); flag++) { if(flag_table[flag].settable){ count++; int l=34-str_len(flag_table[flag].name); bool match=false; if(type_table){ if(value==flag_table[flag].bit){ match=true; } }else{ if(IS_SET(value,flag_table[flag].bit)){ match=true; } } if(flag_table[flag].settable){ c=match?'\'':'$'; }else{ if(match){ c='R'; }else{ // we dont show these flags continue; } } if(type_table && match){ c='/'; // selected option code } const char *suffix; if(count%2==0){ suffix="\r\n"; }else{ suffix=""; } // "{=R %s%20s{x\r\n" ch->printf(FORMATF("`=%c %%s%%%ds`x%s", c, l, suffix), mxp_create_send(ch, FORMATF("sca %s %s %s", command_name, command_name, flag_table[flag].name), flag_table[flag].name), ""); } } ch->println(""); } /**************************************************************************/ // Kal - Dec 2000 void show_olc_options(char_data *ch, const struct flag_type *flag_table, const char *command_name, const char *descript, long flags) { if(is_stat(flag_table)){ ch->printlnf("Syntax: %s <%s type>", command_name, descript); ch->printlnf("Valid %s types include (pick one):", descript); }else{ ch->printlnf("Syntax: %s <%s flag(s)>", command_name, descript); ch->printlnf("Valid %s flags include:", descript); }; show_olc_flags_types_value(ch, flag_table, command_name, flags); } /**************************************************************************/ int mxp_display_olc_flags_ex(char_data *ch, const struct flag_type *flag_table, long value, char *command, char *heading, int max_width /*77*/,int first_indent /*16*/, int indent /*5*/) { int width; int found_count=0; bool type_table=is_stat(flag_table); char *flag_start=""; int lines=0; char openbracket='['; char closebracket=']'; if(type_table){ openbracket='('; closebracket=')'; } char buf[MSL]; int l=first_indent-1-str_len(heading); l=UMAX(l,0); sprintf(buf, FORMATF("`=r%%s%%%ds%c",l, openbracket), mxp_create_send(ch,command, heading), ""); width=first_indent; char flagbuf[MSL]; if(!IS_SET(ch->dyn,DYN_SHOWFLAGS)){ strcat(buf,"`=R"); flag_start=&buf[str_len(buf)-1]; // record where the flags start so we can // strip the mxp later flagbuf[0]='\0'; }; bool match; for(int flag = 0; !IS_NULLSTR(flag_table[flag].name); flag++) { match=false; if(type_table){ if(value==flag_table[flag].bit){ match=true; } }else{ if(IS_SET(value,flag_table[flag].bit)){ match=true; } } if(IS_SET(ch->dyn,DYN_SHOWFLAGS)){ if(flag_table[flag].settable){ if(match){ strcpy(flagbuf,"`='"); }else{ strcpy(flagbuf,"`=$"); } }else{ if(match){ strcpy(flagbuf,"`=\x98"); }else{ // we dont show these flags continue; } } if(type_table && match){ strcpy(flagbuf,"`=/"); // selected option code } }else{ if(!match){ // if they arent using 'showflags', we dont show unset flags continue; } } found_count++; width+= str_len(flag_table[flag].name)+1; if(width>max_width){ strcat(buf,"\r\n"); lines++; strcat(buf,FORMATF(FORMATF("%%%ds", indent), "")); width=indent + str_len(flag_table[flag].name) +1; } strcat(buf, flagbuf); if(flag_table[flag].settable){ strcat(buf, mxp_create_send(ch, FORMATF("sfa %s %s", command, flag_table[flag].name) ,flag_table[flag].name)); }else{ strcat(buf, flag_table[flag].name); } strcat(buf," "); } if(found_count==0){ strcat(buf,"none "); } buf[str_len(buf)-1]='\0'; strcat(buf,FORMATF("`=r%c", closebracket)); if(IS_SET(ch->dyn,DYN_SHOWFLAGS)){ ch->println(buf); }else{ *flag_start='\0'; ch->printlnf("%sR%s", buf, flag_start+1); lines++; } return lines; } /**************************************************************************/ int mxp_display_olc_flags(char_data *ch, const struct flag_type *flag_table, long value, char *command, char *heading) { return mxp_display_olc_flags_ex(ch, flag_table, value, command, heading, 77 /*max_width*/, 16 /*first_indent*/, 5 /*indent*/); } /**************************************************************************/ bool olcex_showflags(char_data *ch, char *) { SET_BIT(ch->dyn,DYN_SHOWFLAGS); run_olc_editor_for_connection(ch->desc, "show"); REMOVE_BIT(ch->dyn,DYN_SHOWFLAGS); return false; } /**************************************************************************/ // does a show after putting argument thru medit() bool olcex_showafter(char_data *ch, char *argument) { if(IS_NULLSTR(argument)){ ch->println("ShowAfter: Shows olc info after the argument is run as a command."); return false; } if(IS_SET(ch->dyn, DYN_USING_OLCAFTER)){ ch->println("No run after loops!"); return false; } SET_BIT(ch->dyn, DYN_USING_OLCAFTER); run_olc_editor_for_connection(ch->desc, argument); REMOVE_BIT(ch->dyn, DYN_USING_OLCAFTER); run_olc_editor_for_connection(ch->desc, "show"); return false; } /**************************************************************************/ // does a command (first arg) after putting argument thru medit() bool olcex_showcommandafter(char_data *ch, char *argument) { char arg[MIL]; argument=one_argument(argument, arg); if(IS_NULLSTR(argument)){ ch->println("ShowCommandAfter: shows a command after all but the first arg is run as a command."); return false; } if(IS_SET(ch->dyn, DYN_USING_OLCAFTER)){ ch->println("No run after loops!"); return false; } SET_BIT(ch->dyn, DYN_USING_OLCAFTER); run_olc_editor_for_connection(ch->desc, argument); REMOVE_BIT(ch->dyn, DYN_USING_OLCAFTER); run_olc_editor_for_connection(ch->desc, arg); return false; } /**************************************************************************/ // does a show after putting argument thru medit() bool olcex_showflagsafter(char_data *ch, char *argument) { if(IS_NULLSTR(argument)){ ch->println("ShowFlagsAfter: ShowsFlags after the argument is run as a command."); return false; } if(IS_SET(ch->dyn, DYN_USING_OLCAFTER)){ ch->println("No run after loops!"); return false; } SET_BIT(ch->dyn, DYN_USING_OLCAFTER); run_olc_editor_for_connection(ch->desc, argument); REMOVE_BIT(ch->dyn, DYN_USING_OLCAFTER); olcex_showflags(ch,""); return false; } /**************************************************************************/ // Kal - Apr 01 char *olcex_get_editor_name( int edit_mode) { switch (edit_mode){ case ED_AREA: return "AEdit"; case ED_ROOM: return "REdit"; case ED_OBJECT: return "OEdit"; case ED_MOBILE: return "MEdit"; case ED_MPCODE: return "MPEdit"; case ED_HELP: return "HEdit"; case ED_BAN: return "BanEdit"; case ED_RACE: return "RaceEdit"; case ED_CLASS: return "ClassEdit"; case ED_SPELLSKILL: return "Spell/SkillEdit"; case ED_COMMAND: return "comEdit"; case ED_DEITY: return "dEdit"; case ED_QUEST: return "qEdit"; case ED_GAME: return "GameEdit"; case ED_SOCIAL: return "SocialEdit"; case ED_HERB: return "HerbEdit"; case ED_MIX: return "MixEdit"; case ED_CLAN: return "ClanEdit"; case ED_SKILLGROUP: return "SkillGroupEdit"; case ED_LANGUAGE: return "LangEdit"; default: return ""; } } /**************************************************************************/ // Kal - Apr 01 const olc_cmd_type *olcex_get_editor_command_table( int edit_mode) { switch (edit_mode){ case ED_AREA: return aedit_table; case ED_ROOM: return redit_table; case ED_OBJECT: return oedit_table; case ED_MOBILE: return medit_table; case ED_MPCODE: return mpedit_table; case ED_HELP: return hedit_table; case ED_BAN: return banedit_table; case ED_RACE: return raceedit_table; case ED_CLASS: return classedit_table; case ED_SPELLSKILL: return sedit_table; case ED_COMMAND: return comedit_table; case ED_DEITY: return dedit_table; case ED_QUEST: return qedit_table; case ED_GAME: return gameedit_table; case ED_SOCIAL: return socedit_table; case ED_HERB: return herbedit_table; case ED_MIX: return mixedit_table; case ED_CLAN: return clanedit_table; case ED_SKILLGROUP: return skillgroupedit_table; case ED_LANGUAGE: return langedit_table; default: return NULL; } } /**************************************************************************/ // Show the commands in an olc editor... display mxp help links for // all entries - Kal, Apr 01 void show_olc_cmds( char_data *ch, const struct olc_cmd_type *olc_table ) { if(!olc_table){ ch->println("show_olc_cmds() given NULL olc_table"); ch->println("- this function is typically called by show_commands()"); return; } int i; int count=0; for(i=0; !IS_NULLSTR(olc_table[i].name); i++){ if(olc_table[i].hidden){ continue; } if(HAS_MXP(ch) && ch->desc){ // automatically make the entries helplinks if a help exists // if not run the command char keyword[MIL]; bool found=false; sprintf(keyword,"OLC%s-%s", uppercase(olcex_get_editor_name(ch->desc->editor)), uppercase(olc_table[i].name)); // search for our generated keyword if(help_get_by_keyword(keyword, ch, false)){ found=true; } // if we have _ in the keyword and we didn't find a help try // converting the _ to a - and see if the help then exists if(!found && count_char(keyword, '_')){ char *p=keyword; while(*p){ if(*p=='_'){ *p='-'; } p++; } // search for modified keyword if(help_get_by_keyword(keyword, ch, false)){ found=true; } } if(found){ // generate the mxp help link ch->printf("`=; %s `x", mxp_create_send(ch, FORMATF("help %s|%s\" hint=\"help %s|%s" ,keyword, olc_table[i].name, keyword, olc_table[i].name) ,FORMATF("%-18.18s", olc_table[i].name)) // text see on screen underlined ); }else{ // generate MXP command links ch->printf("`=: %s `x", mxp_create_send(ch, FORMATF("%s", olc_table[i].name) ,FORMATF("%-18.18s", olc_table[i].name)) ); } }else{ ch->printf(" %-18.18s ", olc_table[i].name); } if(++count%4==0){ ch->println(""); } } if(count%4!=0){ ch->println(""); } } /**************************************************************************/ // Kal - Apr 01 bool show_commands( char_data *ch, char *) { char *line= "========================================================" "========================================================"; char *editorname=uppercase(olcex_get_editor_name(ch->desc->editor)); if(IS_NULLSTR(editorname)){ editorname="[Unknown editor mode name - update olcex_get_editor_name()]"; } ch->titlebarf("%s COMMANDS", editorname); show_olc_cmds( ch, olcex_get_editor_command_table(ch->desc->editor)); char mhelp[MIL]; sprintf(mhelp,"MASTER HELP: `=_OLC-%s. ", uppercase(olcex_get_editor_name(ch->desc->editor))); int len=str_len(mhelp); ch->printlnf("`=t%s[`=T %s`=t]=-`x", (FORMATF(FORMATF("-%%.%ds", 74-len), line)),// the line mhelp); return false; } /**************************************************************************/ bool olcex_tab( char_data *ch, char *argument) { if(IS_NPC(ch)){ ch->println("Players only."); return false; } if(IS_NULLSTR(argument)){ ch->println("syntax: tab <tab number>"); return false; } int value =atoi(argument); if(value>0){ // ch->printlnf("olc tab changed from %d to %d",ch->pcdata->olc_tab+1, value); ch->pcdata->olc_tab=value-1; }else{ ch->println("The tab must be 1 or higher"); } olcex_showflags(ch,""); return false; } /**************************************************************************/ void continents_show( char_data *ch ) { continent_type *c; ch->println( "Current Continental Land Masses" ); ch->println( "===============================" ); int col=0; for( c=continent_list; c; c=c->next){ ch->printf(" %-40s`x", c->name ); if ( ++col % 2 == 0 ){ ch->print_blank_lines(1); } } if ( ++col % 2 == 0 ){ ch->print_blank_lines(1); } return; } /**************************************************************************/ void do_ownerlist( char_data *ch, char *argument ) { char buf[MSL],sbuf[MIL]; int count=0; BUFFER *output; bool all_owners=false; bool search=false; if (!HAS_SECURITY(ch,1)) { ch->println("The ownerlist command is an olc command, you dont have olc permissions."); return; } output= new_buf(); argument =one_argument( argument, sbuf ); if (!IS_NULLSTR(sbuf)) { if (!str_cmp("all", sbuf)) { all_owners=true; } else { search=true; } } // now list all rooms with lockers in them int minvnum=1; int maxvnum=top_vnum_room; // if we arent searching, nor listing all areas reduce the // searching range to the current area if(!search && !all_owners){ minvnum=ch->in_room->area->min_vnum; maxvnum=ch->in_room->area->max_vnum; } int i; ROOM_INDEX_DATA *r; for(i=minvnum; i<=maxvnum; i++){ r=get_room_index(i); if(!r || IS_NULLSTR(r->owner)){ continue; } if(search // filter if specifed && !is_name( sbuf, r->owner ) && !is_name( sbuf, r->invite_list)){ continue; } sprintf( buf, "`x%3d`S[`=R%5d`S-%s%-8.8s`S] `g%s:`w%s`x\r\n", ++count, r->vnum, colour_table[(r->area->vnum%14)+1].code, r->area->short_name, r->owner, r->invite_list); add_buf(output,buf); } if(!count){ add_buf(output,"No rooms with owners/invites found.\r\n"); } if(!search && !all_owners){ add_buf(output,"you can also search this list, or use 'all' to see all matching rooms.\r\n"); } if(GAMESETTING4(GAMESET4_ROOM_INVITES_DISABLED)){ add_buf(output,"Note: the room invites system is disabled in gameedit.\r\n"); } ch->sendpage( buf_string(output)); free_buf(output); } /**************************************************************************/ // Kal, Sept 02 - Count the number of bits set to 1 a long int count_bits(long value) { int count=0; for(int i=0; i<(int)sizeof(long)*8; i++){ if(value&1<<i){ count++; } } return count; } /**************************************************************************/ // Kal, Sept 02 - Finally wrote a generic flag toggling/type setting handler :) bool olc_generic_flag_toggle(char_data *ch, char *argument, const char *command_name, const char *descript, const struct flag_type *flag_table, long *value) { if(!IS_NULLSTR(argument)){ long flags_to_toggle=flag_value( flag_table, argument); if(flags_to_toggle!=NO_FLAG){ if(is_stat(flag_table)){ // types for setting if(*value==flags_to_toggle){ ch->printlnf("The %s type is already set to %s.", descript, flag_string(flag_table, flags_to_toggle)); return false; }else{ ch->printlnf("%s type changed from %s to %s", capitalize(descript), flag_string(flag_table, *value), flag_string(flag_table, flags_to_toggle)); *value=flags_to_toggle; return true; } }else{ // flags for toggling *value^= flags_to_toggle; // do the toggle // see what was toggled on long on=flags_to_toggle & (*value); if(on){ ch->printlnf("%d %s flag%s toggled on: %s", count_bits(on), descript, count_bits(on)==1?"":"s", flag_string(flag_table,on)); } // see what was toggled off long off=flags_to_toggle & (~(*value)); if(off){ ch->printlnf("%d %s flag%s toggled off: %s", count_bits(off), descript, count_bits(off)==1?"":"s", flag_string(flag_table,off)); } } }else{ ch->printlnf("`=X'%s' wasn't recognised as a valid %s flag.`x", argument, descript); show_olc_options(ch, flag_table, command_name, descript, *value); } return true; } show_olc_options(ch, flag_table, command_name, descript, *value); return false; } /**************************************************************************/ // Kal, April 03 - support 'int *', as well as 'long *' above bool olc_generic_flag_toggle(char_data *ch, char *argument, const char *command_name, const char *descript, const struct flag_type *flag_table, int *value) { long lng=(long)*value; bool result=olc_generic_flag_toggle(ch, argument, command_name, descript, flag_table, &lng); *value=(int)lng; return result; } /**************************************************************************/ /**************************************************************************/