Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
rf`

Holy Scripting Wizzerds

Recommended Posts

Oh boy.

I have two problems, but the main one involves scripting. I'm still relatively new to this but I *do* have a basic grasp of it. I'm using the version of ACC that came with DCK 3.62. (so I've no real clue now) And this is for normal Hexen.

The thing is set up that there are four pillars in a room that spew fireballs like a volcano (no problem there). When you shut them off some steps rise and a door opens in the center of the room. You start the shooters by running over a line starting script 14 (which then starts scripts 6,7,8, and 9). You turn off the shooters by pressing them and activating scripts 10,11,12, and 13) The scripts are separate so that you can shut off each trap independently, yet still open the prize when they're all off. The problem is that the 'if(mapvar1 == 4)' part of script 14 doesn't work (at all). I'd like to know why, and how to fix it. Also, if there is a possibility of cleaning up this mess, I'd be glad to hear of it.

I also had no errors while compiling the script. (so you know)

script 6 (void)  
{
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, 30);
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, 30);
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(30, 60));
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(30, 60));
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    thingsound(1, "FIREDEMONATTACK", 127);
    delay(const:8);
    restart;
}

script 7 (void)  
(same as 6 except thing_projectilegravity refers to tid 2)

script 8 (void)  
(same as 6 except thing_projectilegravity refers to tid 3)

script 9 (void)  
(same as 6 except thing_projectilegravity refers to tid 4)

script 10 (int arg0)  
{
    int var0;

    if(var0 == 0)
    {
        ACS_Terminate(arg0, 0);
    }
    var0++; //prevents this script from being run again (4 lines refer to the same script)
    mapvar1++;
}

script 11 (int arg0)  
(same as 10) (turn off separately)

script 12 (int arg0)  
(same as 10) (turn off separately)

script 13 (int arg0)  
(same as 10) (turn off separately)

script 14 (void)  
{
    ACS_Execute(6, 0, 0, 0, 0);
    ACS_Execute(7, 0, 0, 0, 0);
    ACS_Execute(8, 0, 0, 0, 0);
    ACS_Execute(9, 0, 0, 0, 0);
    if(mapvar1 == 4) // one of the problems
    {
        Floor_RaiseByValue(9, 8, 16); // does not work
        delay(const:8);
        Floor_RaiseByValue(12, 8, 32); // these do work
        delay(const:8);
        Floor_RaiseByValue(13, 8, 48); 
        delay(const:8);
        Pillar_Open(14, 8, 16, 64);
    }
}
My second problem is a set of polyobj's that seem to jump track when you stand in their way. I'm setting up side-crushers* and things just seem to screw up. They move in their designed directions, but it seems as if their anchors want to move. I do belive that that's not supposed to happen, is it? This isn't my first dealing with polyobj, just in this way. Does it have anything to do with restarting the script? (IE when it restarts and your in the way, and it resets in a different position?)

Also, one quick question too. What causes runaway scripts?

Edit: I just realizing that I could condense the first four scripts using multiple mapvariables and if;else if statements. :P

Share this post


Link to post

What starts script 14? If nothing starts it, change (void) to OPEN , that way it will start when the map starts. Also:

script 14 OPEN  
{
    ACS_Execute(6, 0, 0, 0, 0);
    ACS_Execute(7, 0, 0, 0, 0);
    ACS_Execute(8, 0, 0, 0, 0);
    ACS_Execute(9, 0, 0, 0, 0);
    ACS_EXECUTE(15, 0, 0, 0, 0);
}

script 15 (void)
{
    if(mapvar1 == 4) // one of the problems
    {
        Floor_RaiseByValue(9, 8, 16); // does not work
        delay(const:8);
        Floor_RaiseByValue(12, 8, 32); // these do work
        delay(const:8);
        Floor_RaiseByValue(13, 8, 48); 
        delay(const:8);
        Pillar_Open(14, 8, 16, 64);
        terminate;
    }
    delay(1);
    restart;
}
Now the script 14 will first start all those scripts, and start script 15. Script 15 will check if mapvar1 is 4. If it is, it will to the bracket stuff and stop. If it isn't, then it will skip the bracket stuff and go on to the restart thing. The script will then restart. I've bolded the added parts.

What causes a runaway script? A runaway script is a script that runs infinite times a second. It has a restart at the end, but it doesn't have any delay(1); If you have a script that runs away, slap in a delay(1); right before that restart.

Share this post


Link to post

script 14 is run by a line trigger; like I said in the second paragraph. :P

Share this post


Link to post

I can spot two problems right off the bat. First off in scripts 10 - 13 var0 (which I presume is var1, var2 etc in sucessive scripts) only has script scope, so it'll be recreated every time you run one of those scripts and acs always inits it to zero so essentially it's useless to have it set up that way.

Next off is that if you check for mapvar == 4 then that will only be true if mapvar is equal to exactly 4. So if you hit one of those other scripts more than once mapvar will incriment past 4 and that script will never work. A short term fix would be making it if(mapvar >= 4) but if you want to clean it up, read on.

You could cut down on the number of redundant scripts by using lineids. Set up the triggers for scripts 10 - 13 to have unique lineids (linesetid();) then in an open script use setlinespecial(x, 80, 10, 0, arg0, x); where x is the lineid for each of the four lines and arg0 is your argument. (those args are line, special (80 is acs_execute) and then some args for acs_execute).

Now in script 10 (scripts 11 - 13 are no longer needed) make it like this:

script 10 (int arg0, int lineid)
{
    ACS_Terminate(arg0, 0);
    setlinespecial(lineid, 0);
    mapvar1++;
}
that will terminate script arg0 and clear all the trigger lines of their special so they cannot be reactivated. That will prevent script 10 from being run more than once per fireball spout and so the highest mapvar1 can ever get is 4 (unless you change it somewhere else of course).

Share this post


Link to post

You can use arg0 on the fireball scripts too, you know. It would remove the need for scripts 7-9. Just run script 6 four times and change ACS_Execute to ACS_ExecuteAlways (so they can run all at once).

Share this post


Link to post

There is no ACS_ExecuteAlways in Hexen, but there are ways around that. Anyway, this is how I might set it up:

int mapvar0;
int mapvar1;
int mapvar2;
int mapvar3;
int mapvar4;

script 6 (void)
{
    if(mapvar0 == 1)
    {
        Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, 30);
        Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, 30);
        Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(30, 60));
        Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(30, 60));
        Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(60, 90));
        Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    thingsound(1, "FIREDEMONATTACK", 127);
    }
    if(mapvar1 == 1)
    {
        Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, 30);
        Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, 30);
        Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, random(30, 60));
        Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, random(30, 60));
        Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, random(60, 90));
        Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    thingsound(2, "FIREDEMONATTACK", 127);
    }
    if(mapvar2 == 1)
    {
        Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, 30);
        Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, 30);
        Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, random(30, 60));
        Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, random(30, 60));
        Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, random(60, 90));
        Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    thingsound(3, "FIREDEMONATTACK", 127);
    }
    if(mapvar3 == 1)
    {
        Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, 30);
        Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, 30);
        Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, random(30, 60));
        Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, random(30, 60));
        Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, random(60, 90));
        Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    thingsound(4, "FIREDEMONATTACK", 127);
    }
    delay(8);
    restart;
}

script 7 (int arg0, int arg1)  
{
    SetLineSpecial(arg1, 0 /* Void */, 0, 0, 0, 0, 0);
    if(arg0 == 1)
    {
        mapvar0 = 0;
    }
    else if(arg0 == 2)
    {
        mapvar1 = 0;
    }
    else if(arg0 == 3)
    {
        mapvar2 = 0;
    }
    else if(arg0 == 4)
    {
        mapvar3 = 0;
    }
    mapvar4++;
    if(mapvar4 == 4)
    {
        Floor_RaiseByValue(9, 8, 16);
        delay(const:8);
        Floor_RaiseByValue(12, 8, 32);
        delay(const:8);
        Floor_RaiseByValue(13, 8, 48); 
        delay(const:8);
        Pillar_Open(14, 8, 16, 64);
    }
}
The first four map variables determine which fireball shooters will be active, and allows you to shut them down in any order. In script 7, arg0 determines which one will be shut down, and arg1 will deactivate that particular line (no need for var0 anymore, so I removed it). Once the script is run four times and mapvar4 = 4, it will trigger the floor raising part of the script.

Share this post


Link to post
The Ultimate DooMer said:

You can use arg0 on the fireball scripts too, you know. It would remove the need for scripts 7-9. Just run script 6 four times and change ACS_Execute to ACS_ExecuteAlways (so they can run all at once).


But if you do that you cannot terminate the scripts anymore and that seems to be something he needs.

Share this post


Link to post

ichor: you could cut down on that a LOT (3/4 of it) by passing the tid of each mapspot as an argument

Share this post


Link to post

I did think about that, but I guess I was in a bit of a hurry, since I'm at work right now. Besides, I'm not so sure that would work.

Share this post


Link to post

Heh, I started working on it again right after Epyo's post. It's slightly on the messy side, but it does work [right].

script 6 (void)  
{
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, 30);
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, 30);
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(30, 60));
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(30, 60));
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    Thing_ProjectileGravity(1, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    thingsound(1, "FIREDEMONATTACK", 127);
    delay(const:8);
    restart;
}

script 7 (void)  
{
    Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, 30);
    Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, 30);
    Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, random(30, 60));
    Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, random(30, 60));
    Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    Thing_ProjectileGravity(2, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    thingsound(2, "FIREDEMONATTACK", 127);
    delay(const:8);
    restart;
}

script 8 (void)  
{
    Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, 30);
    Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, 30);
    Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, random(30, 60));
    Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, random(30, 60));
    Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    Thing_ProjectileGravity(3, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    thingsound(3, "FIREDEMONATTACK", 127);
    delay(const:8);
    restart;
}

script 9 (void)  
{
    Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, 30);
    Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, 30);
    Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, random(30, 60));
    Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, random(30, 60));
    Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    Thing_ProjectileGravity(4, T_FIREBALL1, random(0, 255), 15, random(60, 90));
    thingsound(4, "FIREDEMONATTACK", 127);
    delay(const:8);
    restart;
}

script 10 (int arg0)  
{
    int var0;

    if(var0 == 0)
    {
        ACS_Terminate(arg0, 0);
    }
    var0++;
    mapvar1++;
}

script 11 (int arg0)  
{
    int var0;

    if(var0 == 0)
    {
        ACS_Terminate(arg0, 0);
    }
    var0++;
    mapvar1++;
}

script 12 (int arg0)  
{
    int var0;

    if(var0 == 0)
    {
        ACS_Terminate(arg0, 0);
    }
    var0++;
    mapvar1++;
}

script 13 (int arg0)  
{
    int var0;

    if(var0 == 0)
    {
        ACS_Terminate(arg0, 0);
    }
    var0++;
    mapvar1++;
}

script 14 (void)  
{
    if(mapvar2 == 0)
    {
    ACS_Execute(6, 0, 0, 0, 0);
    ACS_Execute(7, 0, 0, 0, 0);
    ACS_Execute(8, 0, 0, 0, 0);
    ACS_Execute(9, 0, 0, 0, 0);
    ACS_Execute(15, 0, 0, 0, 0);
    mapvar2++;
    }
}

script 15 (void)
{
    if(mapvar1 == 4)
    {
        Floor_RaiseByValue(9, 8, 16);
        delay(const:8);
        Floor_RaiseByValue(12, 8, 32);
        delay(const:8);
        Floor_RaiseByValue(13, 8, 48);
        delay(const:8);
        Pillar_Open(14, 8, 16, 64);
        terminate;
    }
    delay(1);
    restart;
}
I even used what I learned to fix another puzzle on another map. :P

Too bad I still don't unserstand why my sidecrushers behave strangely when I'm in their way.

Oh, and isn't it true that you can only have three arguments per script?

Share this post


Link to post

Yes. It goes like this:

ACS_Execute(script number, map number, arg0, arg1, arg2);
It isn't as limiting as you might think. The most I need is usually one or two arguments. However, ACS_LockedExecute can only use two arguments, since the last number (I think) determines what key you need to activate it.

Share this post


Link to post
Ichor said:

Yes. It goes like this:

ACS_Execute(script number, map number, arg0, arg1, arg2);
It isn't as limiting as you might think. The most I need is usually one or two arguments. However, ACS_LockedExecute can only use two arguments, since the last number (I think) determines what key you need to activate it.

Your right about the ACS_LockedExecute.

So what does ACS_Suspend do?

Share this post


Link to post

You know, I've never actually tried to use that one before. ACS_Suspend temporarily halts the script, and when it resumes (using ACS_Execute again), it continues where it left off. If you used ACS_Terminate and then ACS_Execute, the script would start all over again.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
×