[CODE] While loops in DG scripts

From: Chris Jacobson (fear@ATHENET.NET)
Date: 01/20/98


Heres a WHILE loop "patch-by-hand" for DG scripts.  It'll need a little
changing to compile with your mud, and it works correctly on my MUD.
Your filenames will also differ - I did my port of DG scripts before the
patches came out.

The way they work in scripts:

wait <statement>
...
end

"break" can be used to drop out of not only the current "if" but the
PREVIOUS "block" (if/while) too, since that is what it should do, NOT
exit the script entirely (which is what "halt" is for), or drop back a
single level (which is pretty useless)

If more than 30 loops occur, it will automatically cause a WAIT for 1
second, which WILL pause the MUD.  If more than 100 loops occur since the
script has started executing /from the beginning/ (if it WAITs it will
still remember how many loops), it will mudlog-warn the MUD.

Note that I use George's mudlogf/log patches, among many others (so many
his name is on the login screen, along with the DG people :-).  You will
need to modify the code if you dont have said patches (but only in a
minor way).

Hopefully everything here is whats needed... looks like it to me.

- Chris Jacobson

PS. No credit needed, just dont go telling your builders you wrote it
yerself :-P

-------------------------

*-> in scripts.h:

* add the macro:
#define GET_TRIG_LOOPS(t)               ((t)->loops)

* in trig_data, add:
        int             loops;

* in cmdlist_element, add:
        struct cmdlist_element *original;

*-> scriptengine.c

*> find_end:

replace:
                if (!strn_cmp("if ", p, 3))
with:
                if (!strn_cmp("if ", p, 3) || !strn_cmp("while ", p, 6))

*> find_else_end:

replace:
                if (!strn_cmp("if ", p, 3))
with:
                if (!strn_cmp("if ", p, 3) || !strn_cmp("while ", p, 6))

*> script_driver:

* in the beginning, add these variables:

        struct cmdlist_element *temp;
        UInt32  loops = 0;

* replace:
        if (mode == TRIG_NEW)
                GET_TRIG_DEPTH(trig) = 1;

* with:
        if (mode == TRIG_NEW) {
                GET_TRIG_LOOPS(trig) = 0;
                GET_TRIG_DEPTH(trig) = 1;
        }

* replace "} else if (!strn_cmp("end", p, 3)) { ... }" with:

                } else if (!strn_cmp("while ", p, 6)) {
                        temp = find_end(cl);
                        if (process_if(p + 6, go, sc, trig, type)) {
                                GET_TRIG_DEPTH(trig)++;
                                temp->original = cl;
                        } else {
                                cl = temp;
                        }
                } else if (!strn_cmp("end", p, 3)) {
                        GET_TRIG_DEPTH(trig)--;
                        if (cl->original && process_if(cl->original->cmd + 6, go, sc, trig,
type)) {
                                cl = cl->original;
                                GET_TRIG_DEPTH(trig)++;
                                loops++;
                                GET_TRIG_LOOPS(trig)++;
                                if (loops == 30) {
                                        process_wait(go, trig, type, "wait 1", cl);
                                        depth--;
                                        release_buffer(cmd);
                                        return ret_val;
                                }
                                if (GET_TRIG_LOOPS(trig) == 100) {
                                        mudlogf(NRM, LVL_BUILDER, TRUE, "SCRIPTERR: Trigger VNum %d has
looped 100 times!!!", GET_TRIG_VNUM(trig));
                                }
                        }
                } else if (!strn_cmp("break", p, 5)) {
                        GET_TRIG_DEPTH(trig) -= 2;
                        temp = find_end(cl);
                        if (temp->next) {
                                cl = temp;
                                temp = find_end(cl);
                                if (temp->next)
                                        cl = temp;
                        }
                } else {


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST