Page 1 of 1

z-height of projectile when hitting wall

PostPosted: Sun Sep 12, 2021 3:06 am
by vedan77
Hi,

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

Code: Select allExpand view
 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 allExpand view
#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.