Brew Skill unable to select different spells

  • Nero
  • Nero's Avatar Topic Author
  • Offline
  • Premium Member
  • Premium Member
More
2 weeks 2 days ago - 2 weeks 2 days ago #10150 by Nero
I added Brew Code to my game to have players brew different types of potions using an empty bottle and other resources
One issue I am having is that when I want to brew something say for example 'greater fire resistance' it is going down the list of spells and selecting the first one that matches 'greater' so its creating an frost resistance potion instead of fire resistance. How do I resolve?

I know it's regarding the way the spellname is structured I just don't know how to correct that
/* struct for syls */
struct syllable {
  char *org;
  char *new;
};

/* extern variables */
char *spells;
const char *spellname;
extern struct spell_info_type spell_info;
extern struct syllable syls;

/* extern procedures */
int mag_manacost(struct char_data * ch, int spellnum);

char *get_spell_name(char *argument)
{
  char *s;

  s = strtok(argument, "'");
  s = strtok(NULL, "'");
 
  return s;
}

//Brew Code create a potion spell from an empty container.
char *potion_names = {
    "milky white",
    "bubbling white",
    "icy blue",
    "bubbling yellow",
    "fiery red",
    "gritty brown",
        "light green",
    "dark green",
    "swirling purple",
    "flickering green",
    "cloudy blue",
    "glowing red",
    "sparkling blue",
    "incandescent blue",
        "swirling black",
        "cloudy gray",
        "milky blue",
        "bright green",
        "bright orange",
};

void make_potion(struct char_data *ch, int potion, struct obj_data *container)
{
        struct obj_data *final_potion;
        char buf[MAX_INPUT_LENGTH];
        char buf2[MAX_INPUT_LENGTH];
        int can_make = TRUE, mana, dam, num = 0;
        struct extra_descr_data *new_descr;
        char spell_name[MAX_STRING_LENGTH];

        /* Modify this list to suit which spells you
           want to be able to mix. */
        switch (potion) {
        case SPELL_SANCTUARY:
        num = 0;
        break;
        case SPELL_CURE_BLIND:
        num = 1;
        break;
        case SPELL_IMMUNITY_TO_COLD:
        num = 2;
        break;
        case SPELL_IMMUNITY_TO_ELEC:
        num = 3;
        break;
        case SPELL_IMMUNITY_TO_FIRE:
        num = 4;
        break;
        case SPELL_IMPROVED_INVISIBILITY:
        num = 5;
        break;
        case SPELL_SUSTAIN:
        num = 6;
        break;
        case SPELL_REMOVE_POISON:
        num = 7;
        break;
        case SPELL_REMOVE_CURSE:
        num = 8;
        break;
        case SPELL_STRENGTH:
        num = 9;
        break;
        case SPELL_WORD_OF_RECALL:
        num = 10;
        break;
        case SPELL_SENSE_LIFE:
        num = 11;
        break;
        case SPELL_WATERWALK:
        num = 12;
        break;
        case SPELL_BARKSKIN:
        num = 14;
        break;
        case SPELL_HASTE:
        num = 15;
        break;
        case SPELL_INFRAVISION:
        num = 16;
        break;
        case SPELL_ENLARGE:
        num = 17;
        break;
        case SPELL_REGENERATION:
        num = 18;
        break;
        case SPELL_SHRINK:
        num = 19;
        break;
        default:
        can_make = FALSE;
                break;
        }
        if (can_make == FALSE) {
                send_to_char(ch, "That spell cannot be mixed into a potion.\r\n");
                return;
        }
        else if ((rand_number(1, (GET_CLASS(ch) == CLASS_MAGIC_USER) ? 10 : 3) == 3) && (GET_LEVEL(ch) < LVL_IMMORT))  {
                send_to_char(ch, "As you begin mixing the potion, it violently explodes!\r\n");
                act("$n begins to mix a potion, and it suddenly explodes!", FALSE, ch, 0,0, TO_ROOM);
                extract_obj(container);
                dam = rand_number(5, 50);
                GET_HIT(ch) -= dam;
                update_pos(ch);
                return;
        }

    /* requires x3 mana to mix a potion than the spell, 2x for caster classes */
    /* also costs some ore resource */
   if (GET_CLASS(ch) != CLASS_MAGIC_USER && GET_CLASS(ch) != CLASS_BARD && GET_CLASS(ch) != CLASS_WARLOCK && GET_CLASS(ch) != CLASS_NECROMANCER)
      mana = mag_manacost(ch, potion) * 3;
    else
      mana = mag_manacost(ch, potion) * 2;

        if (GET_MANA(ch) - mana > 0 /*&& GET_STONE(ch) >= 10)*/) {
                GET_MANA(ch) -= mana;
           //     GET_STONE(ch) -= 10;
                sprintf(buf, "You mix some ingredients into the container and create a %s potion.\r\n", potion_names[num]);
                send_to_char(ch, buf);
                act("$n creates a potion!", FALSE, ch, 0, 0, TO_ROOM);
                extract_obj(container);
        }
    //    else if (GET_MANA(ch) - mana <= 0 && GET_STONE(ch) > 0){
     //           send_to_char(ch, "You don't have enough mana to brew a potion!\r\n");
     //           return;
    //    }
        else {
                send_to_char(ch, "You don't have enough ore to brew a potion!\r\n");
                return;
        }

        final_potion = create_obj();
        final_potion->item_number = NOTHING;
        IN_ROOM(final_potion) = NOWHERE;
        final_potion->name = strdup("potion");

       spellname = skill_name(GET_OBJ_VAL(final_potion, potion));

        sprintf(buf2, "A %s potion lies here.", potion_names[num]);
        final_potion->description = strdup(buf2);

        sprintf(buf2, "A %s potion", potion_names[num]);
        final_potion->short_description = strdup(buf2);
        
        /* extra description coolness! */
        CREATE(new_descr, struct extra_descr_data, 1);
        new_descr->keyword = strdup("potion");
        sprintf(buf2, "It appears to be a %s potion.\r\n", potion_names[num]);
        new_descr->description = strdup(buf2);
        final_potion->ex_description = new_descr;

        GET_OBJ_TYPE(final_potion) = ITEM_POTION;
        SET_BIT_AR(GET_OBJ_WEAR(final_potion), ITEM_WEAR_TAKE);
        SET_BIT_AR(GET_OBJ_EXTRA(final_potion), ITEM_NORENT);
        GET_OBJ_VAL(final_potion, 0) = GET_LEVEL(ch);
        GET_OBJ_VAL(final_potion, 1) = potion;
        GET_OBJ_VAL(final_potion, 2) = -1;
        GET_OBJ_VAL(final_potion, 3) = -1;
        GET_OBJ_COST(final_potion) = GET_LEVEL(ch) * 500;
        GET_OBJ_WEIGHT(final_potion) = 1;
        GET_OBJ_RENT(final_potion) = 0;

        obj_to_char(final_potion, ch);
}
Attachments:
Last edit: 2 weeks 2 days ago by Nero.

Please Log in or Create an account to join the conversation.

More
2 weeks 2 days ago #10151 by thomas
Well, have you tried using ' ?

brew bottle 'remove curse'

Please Log in or Create an account to join the conversation.

  • Nero
  • Nero's Avatar Topic Author
  • Offline
  • Premium Member
  • Premium Member
More
2 weeks 1 day ago #10152 by Nero
Yes I have and when I try to add the '' in I get the "Mix what spell?!?" Message.

Please Log in or Create an account to join the conversation.

  • Nero
  • Nero's Avatar Topic Author
  • Offline
  • Premium Member
  • Premium Member
More
2 weeks 1 day ago #10153 by Nero
This is part of the do_brew
        potion = find_skill_num(spell_name);

        if ((potion < 1) || (potion > MAX_SPELLS)) {
                send_to_char(ch, "Mix what spell?!?\r\n");
                return;
        }
        if (GET_LEVEL(ch) < spell_info[potion].min_level[(int) GET_CLASS(ch)]){
                 send_to_char(ch, "You do not know how to make that potion!\r\n");
                return;
        }
        make_potion(ch, potion, container);
}

Please Log in or Create an account to join the conversation.

More
2 weeks 1 day ago #10154 by thomas
Hmm. It seems the problem is outside the code you're showing us; either spell_name is badly parsed (ie, it only contains the value "greater" in the beginning of the previous comment) or the find_skill_num() function is bad.
And that one is a function in stock tba: github.com/tbamud/tbamud/blob/master/src/spell_parser.c#L145

How is spell_name initialized?

Please Log in or Create an account to join the conversation.

  • Nero
  • Nero's Avatar Topic Author
  • Offline
  • Premium Member
  • Premium Member
More
2 weeks 1 day ago #10155 by Nero
Here is the entirety of do_brew our find_skill_num function in spell_parser.c matches TBAmud so it may be an issue with how spell_name is parsing. This function is only here within the act.create.c that I created to house do_brew and other item creation commands.


/* struct for syls */
struct syllable {
  char *org;
  char *new;
};

/* extern variables */
char *spells[];
const char *spellname;
extern struct spell_info_type spell_info[];
extern struct syllable syls[];

/* extern procedures */
int mag_manacost(struct char_data * ch, int spellnum);

char *get_spell_name(char *argument)
{
  char *s;

  s = strtok(argument, "'");
  s = strtok(NULL, "'");
 
  return s;
}

//Brew Code create a potion spell from an empty container.
char *potion_names[] = {
    "milky white",
    "bubbling white",
    "icy blue",
    "bubbling yellow",
    "fiery red",
    "gritty brown",
        "light green",
    "dark green",
    "swirling purple",
    "flickering green",
    "cloudy blue",
    "glowing red",
    "sparkling blue",
    "incandescent blue",
        "swirling black",
        "cloudy gray",
        "milky blue",
        "bright green",
        "bright orange",
};

void make_potion(struct char_data *ch, int potion, struct obj_data *container)
{
        struct obj_data *final_potion;
        char buf[MAX_INPUT_LENGTH];
        char buf2[MAX_INPUT_LENGTH];
        int can_make = TRUE, mana, dam, num = 0;
        struct extra_descr_data *new_descr;
        char spell_name[MAX_STRING_LENGTH];

        /* Modify this list to suit which spells you
           want to be able to mix. */
        switch (potion) {
        case SPELL_SANCTUARY:
        num = 0;
        break;
        case SPELL_CURE_BLIND:
        num = 1;
        break;
        case SPELL_IMMUNITY_TO_COLD:
        num = 2;
        break;
        case SPELL_IMMUNITY_TO_ELEC:
        num = 3;
        break;
        case SPELL_IMMUNITY_TO_FIRE:
        num = 4;
        break;
        case SPELL_IMPROVED_INVISIBILITY:
        num = 5;
        break;
        case SPELL_SUSTAIN:
        num = 6;
        break;
        case SPELL_REMOVE_POISON:
        num = 7;
        break;
        case SPELL_REMOVE_CURSE:
        num = 8;
        break;
        case SPELL_STRENGTH:
        num = 9;
        break;
        case SPELL_WORD_OF_RECALL:
        num = 10;
        break;
        case SPELL_SENSE_LIFE:
        num = 11;
        break;
        case SPELL_WATERWALK:
        num = 12;
        break;
        case SPELL_BARKSKIN:
        num = 14;
        break;
        case SPELL_HASTE:
        num = 15;
        break;
        case SPELL_INFRAVISION:
        num = 16;
        break;
        case SPELL_ENLARGE:
        num = 17;
        break;
        case SPELL_REGENERATION:
        num = 18;
        break;
        case SPELL_SHRINK:
        num = 19;
        break;
        default:
        can_make = FALSE;
                break;
        }
        if (can_make == FALSE) {
                send_to_char(ch, "That spell cannot be mixed into a potion.\r\n");
                return;
        }
        else if ((rand_number(1, (GET_CLASS(ch) == CLASS_MAGIC_USER) ? 10 : 3) == 3) && (GET_LEVEL(ch) < LVL_IMMORT))  {
                send_to_char(ch, "As you begin mixing the potion, it violently explodes!\r\n");
                act("$n begins to mix a potion, and it suddenly explodes!", FALSE, ch, 0,0, TO_ROOM);
                extract_obj(container);
                dam = rand_number(5, 50);
                GET_HIT(ch) -= dam;
                update_pos(ch);
                return;
        }

    /* requires x3 mana to mix a potion than the spell, 2x for caster classes */
    /* also costs some ore resource */
   if (GET_CLASS(ch) != CLASS_MAGIC_USER && GET_CLASS(ch) != CLASS_BARD && GET_CLASS(ch) != CLASS_WARLOCK && GET_CLASS(ch) != CLASS_NECROMANCER)
      mana = mag_manacost(ch, potion) * 3;
    else
      mana = mag_manacost(ch, potion) * 2;

        if (GET_MANA(ch) - mana > 0 /*&& GET_STONE(ch) >= 10)*/) {
                GET_MANA(ch) -= mana;
           //     GET_STONE(ch) -= 10;
                sprintf(buf, "You mix some ingredients into the container and create a %s potion.\r\n", potion_names[num]);
                send_to_char(ch, buf);
                act("$n creates a potion!", FALSE, ch, 0, 0, TO_ROOM);
                extract_obj(container);
        }
    //    else if (GET_MANA(ch) - mana <= 0 && GET_STONE(ch) > 0){
     //           send_to_char(ch, "You don't have enough mana to brew a potion!\r\n");
     //           return;
    //    }
        else {
                send_to_char(ch, "You don't have enough ore to brew a potion!\r\n");
                return;
        }

        final_potion = create_obj();
        final_potion->item_number = NOTHING;
        IN_ROOM(final_potion) = NOWHERE;
        final_potion->name = strdup("potion");

       spellname = skill_name(GET_OBJ_VAL(final_potion, potion));

        sprintf(buf2, "A %s potion lies here.", potion_names[num]);
        final_potion->description = strdup(buf2);

        sprintf(buf2, "A %s potion", potion_names[num]);
        final_potion->short_description = strdup(buf2);
        
        /* extra description coolness! */
        CREATE(new_descr, struct extra_descr_data, 1);
        new_descr->keyword = strdup("potion");
        sprintf(buf2, "It appears to be a %s potion.\r\n", potion_names[num]);
        new_descr->description = strdup(buf2);
        final_potion->ex_description = new_descr;

        GET_OBJ_TYPE(final_potion) = ITEM_POTION;
        SET_BIT_AR(GET_OBJ_WEAR(final_potion), ITEM_WEAR_TAKE);
        SET_BIT_AR(GET_OBJ_EXTRA(final_potion), ITEM_NORENT);
        GET_OBJ_VAL(final_potion, 0) = GET_LEVEL(ch);
        GET_OBJ_VAL(final_potion, 1) = potion;
        GET_OBJ_VAL(final_potion, 2) = -1;
        GET_OBJ_VAL(final_potion, 3) = -1;
        GET_OBJ_COST(final_potion) = GET_LEVEL(ch) * 500;
        GET_OBJ_WEIGHT(final_potion) = 1;
        GET_OBJ_RENT(final_potion) = 0;

        obj_to_char(final_potion, ch);
}

ACMD(do_brew)
{
        struct obj_data *container;
        struct obj_data *obj, *next_obj;
        char bottle_name[MAX_STRING_LENGTH];
        char spell_name[MAX_STRING_LENGTH];
        char buf[MAX_INPUT_LENGTH];
        int potion, found = FALSE;

        two_arguments(argument, bottle_name, spell_name);


        if ((GET_CLASS(ch) == CLASS_FIGHTER || GET_CLASS(ch) == CLASS_THIEF) &&
        GET_LEVEL(ch) < LVL_IMMORT) {
                send_to_char(ch, "You have no idea how to mix potions!\r\n");
                return;
        }

        if (!can_see_room(ch, IN_ROOM(ch))) {
                send_to_char(ch, "It's too dark for you to brew potions!\r\n");
                return;
        }

        /* No brewing while fighting */
        if (IS_FIGHTING(ch)) {
                send_to_char(ch, "You are too busy fighting to brew a potion right now!\r\n");
                return;
        }

        if (!*bottle_name || !*spell_name) {
                send_to_char(ch, "What do you wish to mix in where?\r\n");
                return;
        }

        for (obj = ch->carrying; obj; obj = next_obj) {
            next_obj = obj->next_content;
        if (obj == NULL)
        return;
        if (!(container =  get_obj_in_list_vis(ch->carrying, ch, bottle_name)))
            continue;
        else
            found = TRUE;
        }

        if (found != FALSE && (GET_OBJ_TYPE(container) != ITEM_DRINKCON)) {
        send_to_char(ch, "That item is not a suitable container for brewing potions!\r\n");
        return;
        }

        if (found == FALSE) {
        sprintf(buf, "You don't have a %s in your inventory!\r\n", bottle_name);
        send_to_char(ch, buf);
        return;
        }

        if (found == TRUE && (GET_OBJ_TYPE(container) == ITEM_DRINKCON) && (GET_OBJ_VAL(container, 1) > 0)) {
        send_to_char(ch, "The container needs to be empty before you can brew!\r\n");
        return;
        }

        potion = find_skill_num(spell_name);

        if ((potion < 1) || (potion > MAX_SPELLS)) {
                send_to_char(ch, "Mix what spell?!?\r\n");
                return;
        }
        if (GET_LEVEL(ch) < spell_info[potion].min_level[(int) GET_CLASS(ch)]){
                 send_to_char(ch, "You do not know how to make that potion!\r\n");
                return;
        }
        make_potion(ch, potion, container);
}

Please Log in or Create an account to join the conversation.

  • Nero
  • Nero's Avatar Topic Author
  • Offline
  • Premium Member
  • Premium Member
More
2 weeks 1 day ago #10156 by Nero
Thanks for the tip it looks like the issue was how it was parsing the spell name
here is what I did to fix it:
ACMD(do_brew)
{
        struct obj_data *container;
        struct obj_data *obj, *next_obj;
        char bottle_name[MAX_STRING_LENGTH];
        char spell_name[MAX_STRING_LENGTH];
        char buf[MAX_INPUT_LENGTH];
        char *temp1, *temp2;
        int potion, found = FALSE;

        temp1 = one_argument(argument, bottle_name);
    
    /* sanity check */
    if (temp1) {
        temp2 = get_spell_name(temp1);
        if (temp2)
        strcpy(spell_name, temp2);
    } else {
        bottle_name[0] = '\0';
        spell_name[0] = '\0';
    }

Please Log in or Create an account to join the conversation.

Time to create page: 0.109 seconds