Example #1
0
static void _doc_process_var(doc_ptr doc, cptr name)
{
    if (strcmp(name, "version") == 0)
    {
        string_ptr s = string_alloc_format("%d.%d.%d", VER_MAJOR, VER_MINOR, VER_PATCH);
        doc_insert(doc, string_buffer(s));
        string_free(s);
    }
    else if (strlen(name) > 3 && strncmp(name, "FF_", 3) == 0)
    {
        char buf[100];
        int  f_idx;

        sprintf(buf, "%s", name + 3);
        f_idx = f_tag_to_index(buf);

        if (0 <= f_idx && f_idx < max_f_idx)
        {
            string_ptr s = string_alloc();
            feature_type *feat = &f_info[f_idx];

            string_printf(s, "<color:%c>%c</color>",
                attr_to_attr_char(feat->d_attr[F_LIT_STANDARD]),
                feat->d_char[F_LIT_STANDARD]);

            doc_insert(doc, string_buffer(s));
            string_free(s);
        }
    }
}
Example #2
0
static void _doc_process_tag(doc_ptr doc, doc_tag_ptr tag)
{
    if ( tag->type == DOC_TAG_CLOSE_COLOR
      || tag->type == DOC_TAG_CLOSE_STYLE
      || tag->type == DOC_TAG_CLOSE_INDENT )
    {
        doc_pop_style(doc);
    }
    else if (tag->type == DOC_TAG_COLOR)
    {
        assert(tag->arg);
        if (tag->arg_size == 1)
        {
            if (tag->arg[0] == '*')
                doc_pop_style(doc);
            else
            {
                doc_style_t style = *doc_current_style(doc); /* copy */
                switch (tag->arg[0])
                {
                case 'd': style.color = TERM_DARK; break;
                case 'w': style.color = TERM_WHITE; break;
                case 's': style.color = TERM_SLATE; break;
                case 'o': style.color = TERM_ORANGE; break;
                case 'r': style.color = TERM_RED; break;
                case 'g': style.color = TERM_GREEN; break;
                case 'b': style.color = TERM_BLUE; break;
                case 'u': style.color = TERM_UMBER; break;
                case 'D': style.color = TERM_L_DARK; break;
                case 'W': style.color = TERM_L_WHITE; break;
                case 'v': style.color = TERM_VIOLET; break;
                case 'y': style.color = TERM_YELLOW; break;
                case 'R': style.color = TERM_L_RED; break;
                case 'G': style.color = TERM_L_GREEN; break;
                case 'B': style.color = TERM_L_BLUE; break;
                case 'U': style.color = TERM_L_UMBER; break;
                }
                doc_push_style(doc, &style);
            }
        }
        else
        {
            string_ptr  arg = string_copy_sn(tag->arg, tag->arg_size);
            doc_style_t style = *doc_current_style(doc); /* copy */
            doc_style_f f = _get_doc_style_f(doc, string_buffer(arg));

            if (f)
                f(&style);

            {/* We don't copy the named style, just its color. */
             /* Also, we damn well better push a style or we'll be upset
                when the good little user pops! */
                doc_style_t copy = *doc_current_style(doc);
                copy.color = style.color;
                doc_push_style(doc, &copy);
            }
            string_free(arg);
        }
    }
    else if (tag->type == DOC_TAG_INDENT)
    {
        doc_style_t style = *doc_current_style(doc);
        style.left = doc->cursor.x;
        doc_push_style(doc, &style);
    }
    else
    {
        string_ptr arg = string_copy_sn(tag->arg, tag->arg_size);

        switch (tag->type)
        {
        case DOC_TAG_STYLE:
            if (tag->arg_size == 1 && tag->arg[0] == '*')
                doc_pop_style(doc);
            else
            {/* Better silently add one if name doesn't exist ... */
                doc_style_t copy = *doc_current_style(doc);
                doc_style_f f = _get_doc_style_f(doc, string_buffer(arg));

                if (f)
                    f(&copy);
                doc_push_style(doc, &copy);
            }
            break;
        case DOC_TAG_VAR:
            _doc_process_var(doc, string_buffer(arg));
            break;
        case DOC_TAG_TAB:
        {
            int pos = atoi(string_buffer(arg)) + doc_current_style(doc)->left;
            if (pos > doc->cursor.x)
                doc_insert_space(doc, pos - doc->cursor.x);
            else
                doc_rollback(doc, doc_pos_create(pos, doc->cursor.y));
            break;
        }
        case DOC_TAG_TOPIC:
        {
            doc_bookmark_ptr mark = malloc(sizeof(doc_bookmark_t));
            mark->name = arg; /* steal ownership */
            arg = NULL;
            mark->pos = doc->cursor;
            vec_add(doc->bookmarks, mark);
            break;
        }
        case DOC_TAG_LINK:
        {
            doc_link_ptr link = malloc(sizeof(doc_link_t));
            int          split = string_chr(arg, 0, '#');
            int          ch = 'a' + int_map_count(doc->links);

            if (split >= 0)
            {
                substring_t left = string_left(arg, split);
                substring_t right = string_right(arg, string_length(arg) - split - 1);

                link->file = substring_copy(&left);
                link->topic = substring_copy(&right);
            }
            else
            {
                link->file = arg; /* steal ownership */
                arg = NULL;
                link->topic = NULL;
            }
            link->location.start = doc->cursor;
            int_map_add(doc->links, ch, link);
            {
                /* TODO: This is flawed. Here's a real world example:
                   "(see below <link:birth.txt#PrimaryStats>)."
                   Can you see the problem? We might line break after "[a]" right
                   before ").". Instead, "[a])." should be treated as the current
                   word. To fix this, we'll need a parser with a token queue
                   that we can push onto, but this raises storage issues.
                */
                string_ptr s = string_alloc_format("<style:link>[%c]</style>", ch);
                doc_insert(doc, string_buffer(s));
                string_free(s);

                link->location.stop = doc->cursor;
            }
            break;
        }
        }

        string_free(arg);
    }
}
Example #3
0
void gray_mage_gain_spell(void)
{
    int item;

    if (p_ptr->blind || no_lite())
    {
        msg_print("You cannot see!");
        return;
    }

    if (p_ptr->confused)
    {
        msg_print("You are too confused!");
        return;
    }

    if (!p_ptr->new_spells)
    {
        msg_print("You cannot learn any new spells!");
        return;
    }

    item_tester_hook = _spell_book_p;
    if (get_item(&item, "Study which book?", "You have no books that you can read.", USE_INVEN))
    {
        object_type    *o_ptr = &inventory[item];
        int             spell_idx;
        _slot_info_ptr  slot_ptr;

        /* Pick a spell to learn */
        spell_idx = _choose_spell_to_gain(o_ptr);
        if (spell_idx == -1) return;

        /* Pick a slot for storage (possibly replacing an already learned spell) */
        slot_ptr = _choose("Replace", _ALLOW_EMPTY | _SHOW_INFO);
        if (!slot_ptr) return;

        if (slot_ptr->realm != REALM_NONE)
        {
            string_ptr prompt = string_alloc_format(
                "Really replace %s? <color:y>[y/N]</color>",
                do_spell(slot_ptr->realm, slot_ptr->spell, SPELL_NAME));

            if (msg_prompt(string_buffer(prompt), "ny", PROMPT_DEFAULT) == 'n')
            {
                string_free(prompt);
                return;
            }

            string_free(prompt);
        }

        /* Learn the spell: Note, we don't bother with spell_learned# and spell_order[], since
           these are hard coded for 2 spell realms. Hopefully, ticking up learned_spells is enough? */
        p_ptr->learned_spells++;
        slot_ptr->realm = tval2realm(o_ptr->tval);
        slot_ptr->spell = spell_idx;
        msg_format("You have learned the spell '%s'.", do_spell(slot_ptr->realm, slot_ptr->spell, SPELL_NAME));
        p_ptr->update |= PU_SPELLS;
        p_ptr->redraw |= PR_EFFECTS;
        energy_use = 100;
    }
}