/******************************************************************************/ /* This file contains the various non-OLC commands a wiz uses to edit things * such as skills. * * Note to self: Interactive mode more flexible? How you wanna do this? * * JH 5/25/2004 8:25PM * * $ring0 * */ using namespace std; #include <iostream> #include <vector> #include "merc.h" #include "interp.h" #include "skill.h" #include "skill_code.h" /* Left off: - need to do whatever to d->character->pcdata->menu_locked - make exec_menu for interp--rethink how to do innermost core, the menu is executed, not the function. Know what I mean? But there'll have to be some sort of set function regardless--behind the scenes, let the menu provide the interface. */ /****************************Skill editing section****************************/ bool skill_createmenu(CHAR_DATA *, int); void skill_edit (CHAR_DATA *ch, int foo, bool FirstExecute = false); void do_skill_list(CHAR_DATA *ch, char *argument) { ch_printf(ch, "Skl# Skill Name Magic Type Lvl New?\n\r"); ch_printf(ch, "{y-{Y--{y- {g----------{G---------{g---------- {c---{C----{c--- {m-{M-{m- {r-{R--{r-{x\n\r"); // 1. skull 1 chi for (unsigned int i = 0; i < SkillTable.size(); i++) { ch_printf(ch, "{Y%3d. {G%-30s {C%-10s {M%3d %s{x\n\r", i, SkillTable[i].name.c_str(), magic_table[SkillTable[i].magic_type].name, SkillTable[i].magic_level, SkillTable[i].valid ? "{RNo" : "{GYes"); } return; } //outermost core: pick a skill to edit void do_skill_edit(CHAR_DATA *ch, char *argument) { int skill; if (IS_NPC(ch)) return; MENU_DATA *menuold = NULL; if (!argument || !*argument) { send_to_char("No skill specified. Pick by number. Here's a list of skills.\n\r", ch); do_function(ch, &do_skill_list, ""); send_to_char("Alternatively, you can: {r'{Rskedit save{r'{x, {r'{Rskedit add{r'{x," " {r'{Rskedit validate{r'{x.\n\r", ch); send_to_char("{YNOTE: Be _{RVERY{Y_ sure you truly wish to validate a new skill!\n\r", ch); return; } //fixme what the fuck is going on here? None of the below is acting as it should. if (!is_number(argument)) //save or add or validate { char arg[MIL]; argument = one_argument(argument, arg); if (!str_prefix(arg, "save")) { ch_printf(ch, "Saving skills...\n\r"); if (save_skills()) { ch_printf(ch, "{RError: skill save failed.{x\n\r"); bugf("Skill save failed, called here: %s:%d", __FILE__, __LINE__); return; } ch_printf(ch, "Done.\n\r"); } else if (!str_prefix(arg, "add")) { ch_printf(ch, "argument: %s\n\r", argument); if (argument[0] == '\0') { send_to_char ("Add what skill?\n\r", ch); return; } if (find_skill(argument) >= 0) { send_to_char ("Error: A skill already exists with that name.\n\r", ch); return; } Skill SkAdd; SkAdd.valid = false; SkAdd.name = argument; SkAdd.gsn = MAX_SKILL++; //push another Skill onto the vector ch_printf(ch, "Skill added. Use skedit <number> to edit it.\n\r"); SkillTable.push_back(SkAdd); } else if (!str_prefix(arg, "validate")) //fixme broken. { int which_skill; ch_printf(ch, "argument: %s\n\r", argument); if (argument[0] == '\0') { send_to_char ("Validate what skill?\n\r", ch); return; } which_skill = atoi(argument); if (which_skill < 0 || which_skill > SkillTable.size() - 1) { ch_printf(ch, "blahblah seg fault blah\n\r"); return; } if (SkillTable[which_skill].valid) { ch_printf(ch, "The skill '%s' is already valid.\n\r", SkillTable[which_skill].name.c_str()); } else { //set valid. //add new function parameters to skill_code.h, skill_code.c, //if appropriate. if (SkillTable[which_skill].validate()) { ch_printf(ch, "Skill validated. The MUD will have to be" " recompiled for the skill to be linked to its functions.\n\r\n\r"); do_function(ch, &do_skill_edit, "save"); } } } else { send_to_char("You can: {r'{Rskedit save{r'{x, {r'{Rskedit add{r'{x," " {r'{Rskedit validate{r'{x.\n\r", ch); } return; } skill = atoi (argument); if (skill < 0 || skill >= SkillTable.size()) { send_to_char("Skill choice out of range. Use sklist to pick a skill.\n\r", ch); return; } //valid skill choice entered. Let them know what they're editing. :) //ch_printf(ch, "---Skill %d, '%s'---\n\r", skill, SkillTable[skill].name.c_str()); //hang on...is the person already editing a skill? If so, we have to free. //JH: technically this is impossible, exec_menu requires them to leave a menu //however, if they disconnect, the old menu will be there yet. One would think //that the event handler would take care of it in time, but this is for safety //check: is it necessary? fixme? if ((menuold = find_menu_char (ch, "Skillbuilder")) != NULL) { menu_from_char(ch, menuold); free_menu(menuold); } if (skill_createmenu(ch, skill)) show_menu(ch, ch->pcdata->menu_locked, TRUE); ch_printf(ch, "Hit a number plus its corresponding arguments to change a field.\n\r"); ch_printf(ch, "Example: \n\r> 2 chi\n\r"); ch_printf(ch, "Hit ? to view this skill again, or enter Q or X to quit.\n\r"); } void mf_skedit_name (CHAR_DATA *ch, char *argument) { //MENU_DATA *menu = ch->desc->menu_locked; ch_printf(ch, "The name of a skill is locked and uneditable.\n\r"); } void mf_skedit_mag (CHAR_DATA *ch, char *argument) { int i; MENU_DATA *menu = ch->pcdata->menu_locked; if (menu && argument && *argument) { for (i = 0; i < MAX_MAGIC_TYPE; i++) { if (!str_prefix(magic_table[i].name, argument)) { SkillTable[menu->argi].magic_type = magic_table[i].type; ch_printf(ch, "Skill type of magic changed to %s.\n\r", magic_table[i].name); return; } } } ch_printf(ch, "Unrecognized skill type.\n\r"); } void mf_skedit_lvl (CHAR_DATA *ch, char *argument) { int i; MENU_DATA *menu = ch->pcdata->menu_locked; if (menu && argument && *argument && ((i = atoi(argument)) > 0)) { SkillTable[menu->argi].magic_level = i; ch_printf(ch, "Skill level changed to %d.\n\r", i); } } void mf_skedit_targ (CHAR_DATA *ch, char *argument) { int i; MENU_DATA *menu = ch->pcdata->menu_locked; if (menu && argument && *argument && ((i = atoi(argument)) >= 0)) { SkillTable[menu->argi].target = i; ch_printf(ch, "Skill target changed to %d.\n\r", i); } } void mf_skedit_fla (CHAR_DATA *ch, char *argument) { int i; MENU_DATA *menu = ch->pcdata->menu_locked; if (menu && argument && *argument && ((i = atoi(argument)) >= 0)) { SkillTable[menu->argi].skill_flags = i; ch_printf(ch, "Skill flags changed to %d.\n\r", i); } } void mf_skedit_cos (CHAR_DATA *ch, char *argument) { char arg[MSL]; MENU_DATA *menu = ch->pcdata->menu_locked; if (menu && argument && *argument) { ch_printf(ch, "Skill base costs changed to: "); for (int j = 0; j < MAX_MAGIC_TYPE; j++) { argument = one_argument(argument, arg); SkillTable[menu->argi].base_cost[j] = UMAX(0, atoi(arg)); ch_printf(ch, "{R%d {x%s ", SkillTable[menu->argi].base_cost[j], magic_table[j].name); } } ch_printf(ch, "\n\r"); } void mf_skedit_ukc (CHAR_DATA *ch, char *argument) { char arg[MSL]; MENU_DATA *menu = ch->pcdata->menu_locked; if (menu && argument && *argument) { ch_printf(ch, "Skill upkeep costs changed to: "); for (int j = 0; j < MAX_MAGIC_TYPE; j++) { argument = one_argument(argument, arg); SkillTable[menu->argi].upkeep_cost[j] = UMAX(0, atoi(arg)); ch_printf(ch, "{R%d {x%s ", SkillTable[menu->argi].upkeep_cost[j], magic_table[j].name); } } ch_printf(ch, "\n\r"); } void mf_skedit_lag (CHAR_DATA *ch, char *argument) { MENU_DATA *menu = ch->pcdata->menu_locked; int i; if (menu && argument && *argument && ((i = atoi(argument)) >= 0)) { SkillTable[menu->argi].lag = i; ch_printf(ch, "Skill lag changed to %d.\n\r", i); } } void mf_skedit_las (CHAR_DATA *ch, char *argument) { MENU_DATA *menu = ch->pcdata->menu_locked; int i; if (menu && argument && *argument && ((i = atoi(argument)) > 0)) { SkillTable[menu->argi].hours = i; ch_printf(ch, "Skill longevity ('hours') changed to %d.\n\r", i); } } void mf_skedit_upk (CHAR_DATA *ch, char *argument) { MENU_DATA *menu = ch->pcdata->menu_locked; int i; if (menu && argument && *argument && ((i = atoi(argument)) >= 0)) { SkillTable[menu->argi].upkeep = i; ch_printf(ch, "Skill upkeep timer changed to %d.\n\r", i); } } void mf_skedit_mself (CHAR_DATA *ch, char *argument) { MENU_DATA *menu = ch->pcdata->menu_locked; if (menu && argument[0] == '\0') { ch_printf(ch, "Skill wearoff (self) cleared.\n\r"); SkillTable[menu->argi].off_self = ""; } else if (menu && argument && *argument) { SkillTable[menu->argi].off_self = argument; ch_printf(ch, "Skill wearoff (self) message changed to '%s'.\n\r", argument); } } void mf_skedit_mroom (CHAR_DATA *ch, char *argument) { MENU_DATA *menu = ch->pcdata->menu_locked; if (menu && argument[0] == '\0') { ch_printf(ch, "Skill wearoff (room) cleared.\n\r"); SkillTable[menu->argi].off_room = ""; } if (menu && argument && *argument) { SkillTable[menu->argi].off_room = argument; ch_printf(ch, "Skill wearoff (room) message changed to '%s'.\n\r", argument); } } void mf_skedit_mupk (CHAR_DATA *ch, char *argument) { MENU_DATA *menu = ch->pcdata->menu_locked; if (menu && argument[0] == '\0') { ch_printf(ch, "Skill upkeep (self) cleared.\n\r"); SkillTable[menu->argi].upkeep_self = ""; } if (menu && argument && *argument) { SkillTable[menu->argi].upkeep_self = argument; ch_printf(ch, "Skill upkeep (self) message changed to '%s'.\n\r", argument); } } void mf_skedit_mpuls (CHAR_DATA *ch, char *argument) { MENU_DATA *menu = ch->pcdata->menu_locked; if (menu && argument[0] == '\0') { ch_printf(ch, "Skill pulse (self) cleared.\n\r"); SkillTable[menu->argi].pulse_self = ""; } if (menu && argument && *argument) { SkillTable[menu->argi].pulse_self = argument; ch_printf(ch, "Skill pulse (self) message changed to '%s'.\n\r", argument); } } void mf_skedit_code (CHAR_DATA *ch, char *argument) { MENU_DATA *menu = ch->pcdata->menu_locked; char arg1[MIL]; if (menu && argument && *argument) { argument = one_argument(argument, arg1); if (LOWER(arg1[0]) == 'y') SkillTable[menu->argi].cast_code = dummy_code; else SkillTable[menu->argi].cast_code = NULL; argument = one_argument(argument, arg1); if (LOWER(arg1[0]) == 'y') SkillTable[menu->argi].pulse_code = dummy_code; else SkillTable[menu->argi].pulse_code = NULL; argument = one_argument(argument, arg1); if (LOWER(arg1[0]) == 'y') SkillTable[menu->argi].upkeep_code = dummy_code; else SkillTable[menu->argi].upkeep_code = NULL; argument = one_argument(argument, arg1); if (LOWER(arg1[0]) == 'y') SkillTable[menu->argi].expire_code = dummy_code; else SkillTable[menu->argi].expire_code = NULL; } } bool skill_createmenu(CHAR_DATA *ch, int skill) { char buf[MSL]; char sbuf[MSL]; MENU_DATA *menu = new_menu("Skillbuilder"); OPTION_DATA *option; //for exec_menu menu->argi = skill; SET_BIT(menu->menu_flags, MENU_PHOENIX); //use the fun_from to rebuild the menu menu->fun_from = do_skill_edit; sprintf(buf, "{C[{Gnam{C] {cName of skill {r[{Rlocked{r]{C: %s{x", SkillTable[skill].name.c_str()); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_name; append_option(menu, option); sprintf(buf, "{C[{Gmag{C] {cType of magic{C: %s{x", magic_table[SkillTable[skill].magic_type].name); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_mag; append_option(menu, option); sprintf(buf, "{C[{Glvl{C] {cLevel of magic required{C: %d{x", SkillTable[skill].magic_level); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_lvl; append_option(menu, option); sprintf(buf, "{C[{Gtar{C] {cValid skill targets{C: %d{x", SkillTable[skill].target); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_targ; append_option(menu, option); sprintf(buf, "{C[{Gfla{C] {cSkill flags{C: %d{x", SkillTable[skill].skill_flags); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_fla; append_option(menu, option); sprintf(buf, "{C[{Gcos{C] {cBase cast costs[%d]{C: {x", MAX_MAGIC_TYPE); for (int i = 0; i < MAX_MAGIC_TYPE; i++) { sprintf(sbuf, "{C%d {x", SkillTable[skill].base_cost[i]); strcat(buf, sbuf); } option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_cos; append_option(menu, option); sprintf(buf, "{C[{Gukc{C] {cUpkeep costs per upkeep round[%d]{C: {x", MAX_MAGIC_TYPE); for (int i = 0; i < MAX_MAGIC_TYPE; i++) { sprintf(sbuf, "{C%d {x", SkillTable[skill].upkeep_cost[i]); strcat(buf, sbuf); } option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_ukc; append_option(menu, option); sprintf(buf, "{C[{Glag{C] {cReadiness lag (RT seconds){C: %d{x", SkillTable[skill].lag); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_lag; append_option(menu, option); sprintf(buf, "{C[{Glas{C] {cBase last seconds{C: %d{x", SkillTable[skill].hours); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_las; append_option(menu, option); sprintf(buf, "{C[{Gupk{C] {cUpkeep time{C: %d{x", SkillTable[skill].upkeep); strcat(buf, "\n\r{C--------------------------------------------------------------------------------{x"); strcat(buf, "\n\r{G---{yMessages{G---"); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_upk; append_option(menu, option); sprintf(buf, "{C[{Gmself{C] {cWear-off message (self){C: %s{x", SkillTable[skill].off_self.c_str()); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_mself; append_option(menu, option); sprintf(buf, "{C[{Gmroom{C] {cWear-off message (room){C: %s{x", SkillTable[skill].off_room.c_str()); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_mroom; append_option(menu, option); sprintf(buf, "{C[{Gmupk{C] {cUpkeep message (self){C: %s{x", SkillTable[skill].upkeep_self.c_str()); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_mupk; append_option(menu, option); sprintf(buf, "{C[{Gmpuls{C] {cPulse message (self){C: %s{x", SkillTable[skill].pulse_self.c_str()); strcat(buf, "\n\r{C--------------------------------------------------------------------------------{x"); strcat(buf, "\n\r{G---{ySkill Prerequisites{G---"); strcat(buf, "\n\r{G<list of other named skills added here, e.g. 'haste'>{x"); strcat(buf, "\n\r{C--------------------------------------------------------------------------------{x"); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_mpuls; append_option(menu, option); //set code options for freshly-created skills. if (!SkillTable[skill].valid) { const char *nostr = "{RNo{x"; const char *yesstr = "{GYes{x"; sprintf(buf, "{y[{Ycode{y] {cCustom code for:" " {CCast? %s {CPulse? %s {CUpkeep? %s {CExpire? %s{x", SkillTable[skill].cast_code ? yesstr : nostr, SkillTable[skill].pulse_code ? yesstr : nostr, SkillTable[skill].upkeep_code ? yesstr : nostr, SkillTable[skill].expire_code ? yesstr : nostr); option = new_option(); option->args[0] = str_dup(buf); option->fun_call = mf_skedit_code; append_option(menu, option); } //let the event attach the menu to the ch //menu_to_char(ch, menu); menu_event(ch, menu); //locking will be independent of events. 6/10/2004 11:26PM JH: NOT ANYMORE! //return menu_lock(ch, menu); return true; }