Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
smeghammer

ACS count and linedef trigger

Recommended Posts

I thought I'd share some learning I just went though - hopefully it might help someone else...

 

So on a level for my Hellbreach wad, I wanted a trap with a demon cage opened by W1 linedefs. I wanted it to be triggered from one of several lines (so it would trigger from any direction):

 

40363973_Screenshotfrom2020-05-3109-05-02.png.5c209e1140e7689561b739af5d6b653e.png

 

1972439043_Screenshotfrom2020-05-3109-07-00.png.88f2bbb00511b24fc4a4fce6af2e8a75.png

 

Originally, I had floor_lowerbyvalue action attached to each line and specifying an argument such that a lip still protruded. This worked fine if only ONE line was ever crossed. Crossing other lines with the same action special re-triggered the lowering so the lip disappeared on the second line cross, and all other lines (on first crossing) triggered as well.

 

So to achieve what I wanted I needed a flag of is_opened (or something) with a wider scope than the linedef. Therefore, I played around with a simple ACS script with a variable outside of the numbered script. As an aside, I also discovered that ACS does not use a true boolean type - it uses 'truthy' or 'falsy' (https://zdoom.org/wiki/Data_types#Boolean).

 

Anyway, I made a test WAD which detects and acts on a flag being truthy or not, and also uses a counter to sequentially lower four platforms, regardless of which order you cross the triggering linedefs:

#include "zcommon.acs"

bool triggered = 0;
int counter = 0;


script 1 (void){
    counter++;
    if(triggered == 0){
        print(s:"trigger");
        triggered++;
    }
    else{
        print(s:"already triggered");
    }
    print(i:counter);
    /*
    lower plats on each increment:
    */
    int tagnum = -1;
    switch(counter){
        case 1:
            tagnum=2;
        break;
        
        case 2:
            tagnum=3;
        break;
        
        case 3:
            tagnum=4;
        break;
        
        case 4:
            tagnum=5;
        break;
        
        default:
    }
    floor_lowerbyvalue(tagnum,16,56);
}

The linedefs now use an action special of 80 with a single param of the script number (with WR so you can see the counter increment). 

 

As you can see, I set two map-level variables for the if/else clause and the switch/case clause and each is set regardless of which lines on the map I cross and in what order. I still eventually use the action special floor_lowerbyvalue to lower the four platforms in tag order (yes, it should be inside a condition for 2<=tagnum<=5, but hey, this was a test...).

 

Hopefully this will be of use to someone else.

 

You can get the test WAD from my github site here.

 

 

 

 

 

 

 

Share this post


Link to post

Personally my approach for this kind of things is to have the lines that can trigger the effect all have the same lineID, and to have the script clear all specials from the lines with that lineid. As a result, when one line is crossed and the effect is activated, all other lines get cleared too, and it's impossible to retrigger the effect.

 

A variant of this approach is to have the effect not triggered by lines, but by a sector action, typically SecActEnter or SecActExit. If your lines correspond to the entire perimeter of a sector, so that the trap is triggered when the player enters (or leaves, if they got here via a teleporter) then the sector action can be a simpler implementation of the effect. As a bonus, the lines can still have their own separate effect, for example you could make a teleport pad where the lines will teleport you (as usual) but there's also a sector action when you leave the pad.

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
×