A_SprayDecal As A Replacement For Blood Decal Generation

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!)

A_SprayDecal As A Replacement For Blood Decal Generation

Postby 22alpha22 » Fri May 20, 2022 8:11 pm

Because of issues outlined in these two threads, (viewtopic.php?f=18&t=74509) (viewtopic.php?f=15&t=73639) I am trying implement my own blood decal generation system. A_SprayDecal used from within DamageMObj looks like it will accomplish the task but I am having trouble figuring out precisely how it works. The wiki doesn't seem to know how the offset or direction parameters work and has no examples. With some tinkering and testing, I've got the offset parameter figured out but I still don't understand the direction parameter.

I've checked the source and found this which I think is what A_SprayDecal calls natively but I'm not sure.
Code: Select allExpand view
void SprayDecal(AActor *shooter, const char *name, double distance, DVector3 offset, DVector3 direction, bool useBloodColor, uint32_t decalColor)
{
   //just in case
   if (!shooter)
      return;

   FTraceResults trace;
   DVector3 off(0, 0, 0), dir(0, 0, 0);

   //use vanilla offset only if "custom" equal to zero
   if (offset.isZero() )
      off = shooter->PosPlusZ(shooter->Height / 2);

   else
      off = shooter->Pos() + offset;

   //same for direction
   if (direction.isZero() )
   {
      DAngle ang = shooter->Angles.Yaw;
      DAngle pitch = shooter->Angles.Pitch;
      double c = pitch.Cos();
      dir = DVector3(c * ang.Cos(), c * ang.Sin(), -pitch.Sin());
   }
   
   else
      dir = direction;

   uint32_t bloodTrans = useBloodColor ? shooter->BloodTranslation : 0;
   PalEntry entry = !useBloodColor ? (PalEntry)decalColor : shooter->BloodColor;

   if (Trace(off, shooter->Sector, dir, distance, 0, ML_BLOCKEVERYTHING, shooter, trace, TRACE_NoSky))
   {
      if (trace.HitType == TRACE_HitWall)
      {
         DImpactDecal::StaticCreate(shooter->Level, name, trace.HitPos, trace.Line->sidedef[trace.Side], NULL, entry, bloodTrans);
      }
   }
}

I'm not a programmer and I'm having a bit of trouble figuring out exactly how this function works. I searched around in the source to see if I could find where exactly an actor calls whatever function is used to generate blood decals but I couldn't find it.

Here is what I know about A_SprayDecal and what I need help with:

Name: Fairly obvious, the name of the decal to spawn. I already have my own function which can supply the appropriate decal name.

Distance: Also obvious, the maximum distance from the calling actor that the decal can spawn. It would however be nice to know what the max distance value is that the hardcoded blood decal generation system uses.

Offset: Required a bit of testing to figure it out but it seems that the Vector is an offset based on the calling actors current position. Vector.X is the offset on the X axis, Vector.Y is the offset on the Y axis, and Vector.Z is the offset on the Z axis. Makes sense but note that the offsets are NOT relative to the actors facing. Like distance, it would be helpful to know exactly how the hardcoded blood decal generation handles offsets.

Direction: I haven't been able to figure out how this parameter works. If it was a Vector2, then I would assume one value would be for Angle and the other for Pitch, but since it is a Vector3, I have no idea. Understanding how this parameter works and how exactly the hardcoded blood generation calculates the direction is the single most important part of getting my custom blood generation working.

Thanks ahead of time for any help on this. :)
User avatar
22alpha22
So lonely...
 
Joined: 21 Feb 2014
Location: Montana, USA
Operating System: Windows 10/8.1/8/201x 64-bit
Graphics Processor: nVidia with Vulkan support

Return to Scripting

Who is online

Users browsing this forum: Xeotroid and 3 guests