z-height of projectile when hitting wall

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
vedan77
Posts: 20
Joined: Fri Aug 20, 2021 5:09 am

z-height of projectile when hitting wall

Post by vedan77 »

Hi,

Sluggard gave me a DECORATE modification for projectiles that call a script in their death state:

Code: Select all

 ACTOR Projectile
{
    Radius          20
    Height          10
    Speed           20
    Damage          30

    PROJECTILE
    
    States
    {
        Spawn:
            MISL A 3 
            Loop

        Death:
            MISL B 8 Bright A_Explode
            TNT1 A 0 ACS_ExecuteWithResult(999,0,0,0,0)      // script to return z position of projectile
            MISL C 6 Bright
            MISL D 4 Bright
            Stop

        XDeath:
            MISL B 8 Bright A_Explode
            MISL C 6 Bright
            MISL D 4 Bright
            Stop

        Crash:
            MISL B 8 Bright A_Explode
            MISL C 6 Bright
            MISL D 4 Bright
            Stop
    }
} 
But according to the code, ACS_ExecuteWithResult has no parameters that I could use.

What do I have to change in the code? Is there some self.z that I can give the ACS function as parameter?

I don't have any experience with zscript or the decorate lump. So I don't know where to put this at all (since I use ACS). Add a DECORATE.txt to my resource pk3? Or to my WAD?

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

Why I totally need this:

I recently I saw a short clip of a "destructable" column in Doom which uses projectile activation that triggers a raise/lower - ceiling/floor on a segmented column. It was nice so watch, but it just seemed to lack something.

Unfortunately, I did not bookmark it and can't find it anymore, BUT:

If a projectile creates a texture on it's death on a wall at a certain height, there is a way to get the z coordinate of the projectile.

So if I:

- create a multi-ringed, vertex-connected / meshed column...
- with its floor & ceiling in its middle...
- tag all of its sectors...
- add a custom function to each linedef of each ring that returns the z-coordinate of the projectile impact...

...THEN:

- the column sector floor & ceiling instantly lower/raise themselves to that coordinate relative to the column (in case floor height is not 0)
- column sector floor lowers by a small amount
- column sector ceiling raises by a small amount

This way, a column could be created that is destructible, even up to the point that one should be also able to shoot a hole into it.

But ID need the z coordinate for that^^

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

UPDATE: I recreated the column, it consists of 83 sectors and one ACS function => DOWNLOAD

The code so far:

Code: Select all

#include "zcommon.acs"

script 1 (int sector, int startsector) {

	// variables

	int minheight   = 0;										// COLUMN FLOOR HEIGHT
	int maxheight   = 128;										// COLUMN CEILING HEIGHT
	int splitheight = 1;
	int ring        = 3;
	int innersector = 0;

	bool inside     = FALSE;

	int ceil_z  = 0;
	int floo_z  = 0;
	int ceil1_z = 0;
	int floo1_z = 0;
	int ceil2_z = 0;
	int floo2_z = 0;
	int ceil3_z = 0;
	int floo3_z = 0;
	int ceil4_z = 0;
	int floo4_z = 0;
	int ceil5_z = 0;
	int floo5_z = 0;

	// hit from outside ---------------------------------------------------------------------

		ceil1_z = GetSectorCeilingZ(sector, 0, 0) >> 16;			// GET RING FLOOR HEIGHTS
		floo1_z = GetSectorFloorZ(sector, 0, 0)   >> 16;

		ceil2_z = GetSectorCeilingZ(sector - 26, 0, 0) >> 16;
		floo2_z = GetSectorFloorZ(sector - 26, 0, 0)   >> 16;

		ceil3_z = GetSectorCeilingZ(sector - 52, 0, 0) >> 16;
		floo3_z = GetSectorFloorZ(sector - 52, 0, 0)   >> 16;

		ceil5_z = GetSectorCeilingZ(startsector + 82, 0, 0) >> 16;
		floo5_z = GetSectorFloorZ(startsector + 82, 0, 0)   >> 16;

		// outer rings
		
		if (ring == 3) {											// THIRD OUTER RING
			if (ceil1_z + splitheight < maxheight) {
				Ceiling_RaiseInstant(sector, 0, splitheight);
			} else {ring = 2;}
			if (floo1_z - splitheight > minheight) {
				Floor_LowerInstant(sector, 0, splitheight);
			} else {ring = 2;}
		}
		
		if (ring == 2) {											// SECOND OUTER RING
			if (ceil2_z + splitheight < maxheight) {
				Ceiling_RaiseInstant(sector - 26, 0, splitheight);
			} else {ring = 1;}
			if (floo2_z - splitheight > minheight) {
				Floor_LowerInstant(sector - 26, 0, splitheight);
			} else {ring = 1;}
		}
		
		if (ring == 1) {											// FIRST OUTER RING
			if (ceil3_z + splitheight < maxheight) {
				Ceiling_RaiseInstant(sector - 52, 0, splitheight);
			} else {ring = 0;}
			if (floo3_z - splitheight > minheight) {
				Floor_LowerInstant(sector - 52, 0, splitheight);
			} else {ring = 0;}
		}
		

		// inner ring

		if (ring == 0) {											// INNER RING
			if (sector >= startsector + 52 && sector <= startsector + 58) {innersector = startsector + 78;}
			if (sector >= startsector + 59 && sector <= startsector + 64) {innersector = startsector + 79;}
			if (sector >= startsector + 65 && sector <= startsector + 71) {innersector = startsector + 80;}
			if (sector >= startsector + 72 && sector <= startsector + 77) {innersector = startsector + 81;}

			ceil4_z = GetSectorCeilingZ(innersector, 0, 0) >> 16;	// GET CEILING & FLOOR HEIGHT OF INNER RING
			floo4_z = GetSectorFloorZ(innersector, 0, 0)   >> 16;

			if (ceil4_z + splitheight < maxheight) {
				Ceiling_RaiseInstant(innersector, 0, splitheight);
			} else {ring = -1;}
			if (floo4_z - splitheight > minheight) {
				Floor_LowerInstant(innersector, 0, splitheight);
			} else {ring = -1;}
		}
		
		// center
		
		if (ring == -1) {
			if (ceil5_z + splitheight < maxheight) {				// CENTER
				Ceiling_RaiseInstant(startsector + 82, 0, splitheight);
			} else {inside = TRUE;}
			if (floo5_z - splitheight > minheight) {
				Floor_LowerInstant(startsector + 82, 0, splitheight);
			} else {inside = TRUE;}
		}
		
		// hit from inside -------------------------------------------------------------------------------------
		
		if (inside) {
			
			int inner = 0;
			
			if (sector >= startsector + 52 && sector <= startsector + 58) {inner = startsector + 80;}
			if (sector >= startsector + 59 && sector <= startsector + 64) {inner = startsector + 81;}
			if (sector >= startsector + 65 && sector <= startsector + 71) {inner = startsector + 78;}
			if (sector >= startsector + 72 && sector <= startsector + 77) {inner = startsector + 79;}
				
			if (sector >= startsector + 52 && sector <= startsector + 64) {sector -= 39;} else {sector -= 65;}
				
			int ceil9_z = GetSectorCeilingZ(inner, 0, 0) >> 16;
			int floo9_z = GetSectorFloorZ(inner, 0, 0)   >> 16;

			int ceil6_z = GetSectorCeilingZ(sector, 0, 0) >> 16;
			int floo6_z = GetSectorFloorZ(sector, 0, 0)   >> 16;

			int ceil7_z = GetSectorCeilingZ(sector + 26, 0, 0) >> 16;
			int floo7_z = GetSectorFloorZ(sector + 26, 0, 0)   >> 16;

			int ceil8_z = GetSectorCeilingZ(sector + 52, 0, 0) >> 16;
			int floo8_z = GetSectorFloorZ(sector + 52, 0, 0)   >> 16;


			if (ceil9_z + splitheight < maxheight) {							// INNER
				Ceiling_RaiseInstant(inner, 0, splitheight);
			} else {ring = 1;}
			if (floo9_z - splitheight > minheight) {
				Floor_LowerInstant(inner, 0, splitheight);
			} else {ring = 1;}
			
			if (ring == 1) {
				if (ceil6_z + splitheight < maxheight) {						// FIRST INNER RING
					Ceiling_RaiseInstant(sector, 0, splitheight);
				} else {ring = 2;}
				if (floo6_z - splitheight > minheight) {
					Floor_LowerInstant(sector, 0, splitheight);
				} else {ring = 2;}
			}				

			if (ring == 2) {
				if (ceil7_z + splitheight < maxheight) {						// SECOND INNER RING
					Ceiling_RaiseInstant(sector + 26, 0, splitheight);
				} else {ring = 3;}
				if (floo7_z - splitheight > minheight) {
					Floor_LowerInstant(sector + 26, 0, splitheight);
				} else {ring = 3;}
			}

			if (ring == 3) {													// THIRD INNER RING
				if (ceil8_z + splitheight < maxheight) {
					Ceiling_RaiseInstant(sector + 52, 0, splitheight);
				}
				if (floo8_z - splitheight > minheight) {
					Floor_LowerInstant(sector + 52, 0, splitheight);
				}
			}
		}
}
If I had the impact Z coordinate , those rules then could be applied:

a) start to split at height of impact point
b) if column floor part is hit -> lower floor to height of impact point (and similar for ceiling)
c) if split is big enough and gets shot -> check next ring and apply rule b)

Column in Editor -|- Column ingame

UPDATE:
1. I enhanced the script so that parts of the column can be shot from inside out. That was tricky....
2. Almost all fixed numbers are gone EXCEPT ceilingheight & floorheight of the room at the beginning of the script.
3. A second column has been added to the demo wad.

Return to “Scripting”