Spawning direction checks in DECORATE

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!)
User avatar
Ryuhi
Posts: 355
Joined: Tue Feb 21, 2017 11:00 pm

Spawning direction checks in DECORATE

Post by Ryuhi »

A buddy of mine has a fantastic voxel project going on, and we're running into the common issues with them in regards to which direction they are naturally facing when spawned by the map. I have been trying to come up with a fix using the heretic key Gizmos as a base, since they come in sets of 2s and his voxel art has them as facing front and back while the sides are quite obvious. My methodology is to use A_SpawnItemEX to have "distance check" items spawn as targets, and have the gizmo turn 180 degrees from the closest one (effectively making it face away from whatever the closest wall is) in a single spawn time check (to minimize processing load)

here's my code, the problem I'm having is trying to get the check to occur in all 4 directions. So far as it stands, it works for any free standing instances against a single wall: the problem occurs with any gizmos that are in corners or near angled walls, and I was hoping someone might be able to help me iron things out.

Code: Select all

ACTOR RV_KeyGizmoYellow : KeyGizmoYellow replaces KeyGizmoYellow
{
	states
	{
	Spawn:
	TNT1 A 0 A_SpawnItemEX("WallCheck",0,0,0,100,0,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
	TNT1 A 0 A_SpawnItemEX("WallCheck",0,0,0,0,-100,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
	TNT1 A 0 A_SpawnItemEX("WallCheck",0,0,0,0,100,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
	TNT1 A 0 A_SpawnItemEX("WallCheck",0,0,0,-100,0,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
	KGZ1 A 2 A_CheckProximity("Turning","WallCheck",64)
	Goto Idle
	Turning:
	KGZ1 A 1 A_FaceTarget
	KGZ1 A 1 A_SetAngle(180+Angle)	
	Goto Idle
	Idle:
    KGZ1 A 1
    KGZ1 A 1 A_SpawnItemEx("KeyGizmoFloatYellow", 0, 0, 60)
    KGZ1 A -1
    Stop
	}
}

ACTOR WallCheck
{
	+THRUACTORS
	States
	{
	Spawn:
   TNT1 A 6
	TNT1 A 1 A_Remove(AAPTR_DEFAULT)
	Stop
	}
}
(Keeping the example to vanilla Heretic, this fixes the issue on E1M1, E3M1, E4M1 but not E2M1 and E5M1) Ironically changing the angle from 180 to 90 fixes those instances, but breaks the others. without this decorate code, their natural map placements are correct on E3M1 and E4M1, but incorrect on episodes 1 2 and 5.

I know Heretic isnt the most popular, but if I can get this method working correctly it should be able to be used with the other games as well
Drake Raider
Posts: 473
Joined: Fri Jul 18, 2008 12:27 pm

Re: Spawning direction checks in DECORATE

Post by Drake Raider »

It isn't a solution directly for the problem, but a workaround could be using an ACS map check that tells is whether to rotate or not. Using GetLevelInfo could return the map, and if its one with a none problem for that actor it could use a 90 degree turn instead.

wouldn't be very compatible with map packs though, unless someone wanted to make patches.

Alternatively, run each at one one at a time, and change angle after each direction, see if it makes a difference?

EDIT:

Just thought of using a usr-var to mark the closest distance, and using Check Prox to change it's value? I might be wrong there though.

Seems like you just need a way to compare distances and go with the closest one.

EDIT 2:

Scratch that. Think I solved it.

Code: Select all

ACTOR RV_KeyGizmoYellow : KeyGizmoYellow replaces KeyGizmoYellow
{
   states
   {
   Spawn:
   TNT1 A 0 A_SpawnItemEX("WallCheck",0,0,0,100,0,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
   TNT1 A 0 A_SpawnItemEX("WallCheck",0,0,0,0,-100,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
   TNT1 A 0 A_SpawnItemEX("WallCheck",0,0,0,0,100,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
   TNT1 A 0 A_SpawnItemEX("WallCheck",0,0,0,-100,0,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
   KGZ1 A 1 A_CheckProximity("Turning2","WallCheck",64,2)
   KGZ1 A 2 A_CheckProximity("Turning","WallCheck",64)
   Goto Idle
   Turning:
   KGZ1 A 1 A_FaceTarget
   KGZ1 A 1 A_SetAngle(180+Angle)   
   Goto Idle
   Turning2:
   KGZ1 A 1 A_FaceTarget
   KGZ1 A 1 A_SetAngle(90+Angle)   
   Goto Idle
   Idle:
    KGZ1 A 1
    KGZ1 A 1 A_SpawnItemEx("KeyGizmoFloatYellow", 0, 0, 60)
    KGZ1 A -1
    Stop
   }
}
User avatar
Ryuhi
Posts: 355
Joined: Tue Feb 21, 2017 11:00 pm

Re: Spawning direction checks in DECORATE

Post by Ryuhi »

Unfortunately it doesnt work, as when used with the key gizmos it still seems to have some facing correctly and others not. with the code from edit 2, it is correct on E2M1 and E5M1, but incorrect on E1/3/4.

the acs script is a neat idea but yeah compatibility would be a bit low.

as for edit one, you're right, we just need a way of finding which one is closest. i think the problem comes from when they are placed in corners, as there are two directions that are coming up as the "closest" and messing up the calculation.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 48040
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Spawning direction checks in DECORATE

Post by Graf Zahl »

I don't think this can be solved in a robust way with DECORATE. Using ZScript and a BlockLinesIterator would allow you to do far more thorough checks of the actor's surroundings.
User avatar
Apeirogon
Posts: 1603
Joined: Mon Jun 12, 2017 12:57 am

Re: Spawning direction checks in DECORATE

Post by Apeirogon »

Try
Spoiler:
User avatar
Ryuhi
Posts: 355
Joined: Tue Feb 21, 2017 11:00 pm

Re: Spawning direction checks in DECORATE

Post by Ryuhi »

we got this version to work correctly on all heretic maps, with a variation for each colored key gizmo. This was being done mainly for Reikall's "Yet Another Voxel Project" viewtopic.php?f=46&t=58340 so the gizmos were one of the most pressing ones since they looked especially awkward when placed sideways. Hopefully when I learn zscript I'll have a more elegant solution, but for now it seems to be working pretty well :D

Code: Select all

ACTOR WallCheck
{
    Radius 5
    +MISSILE
    +THRUACTORS
    +NOGRAVITY
    States
    {
    Spawn:
       TNT1 A 3
       TNT1 A 1 A_Remove(AAPTR_DEFAULT)
        Stop
    death:
       TNT1 A 2
       TNT1 A 1 A_Remove(AAPTR_DEFAULT)
        Stop
    }
}

ACTOR RV_KeyGizmoGreen : KeyGizmoGreen replaces KeyGizmoGreen
{
   -FIXMAPTHINGPOS
   States
   {
    Spawn:
        KGZ1 A 0 NoDelay A_JumpIf(GetCVAR("sv_altkeygizmo") == 0, "Idle")
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,0,20,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",16)
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,0,-20,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",16)
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,20,0,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",16)
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,-20,0,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",16)
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,0,20,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",24)
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,0,-20,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",24)
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,20,0,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",24)
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,-20,0,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",24)
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,0,20,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",40)
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,0,-20,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",40)
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,20,0,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",40)
        KGZ1 A 2 A_SpawnItemEX("WallCheck",0,0,32,-20,0,0,0,SXF_ISTARGET|SXF_ABSOLUTEVELOCITY)
        KGZ1 A 0 A_CheckProximity("Turning","WallCheck",40)
        KGZ1 A 0 A_SetAngle(270)
        Goto Idle
    Turning:
        KGZ1 A 1 A_FaceTarget
        KGZ1 A 1 A_SetAngle(180+Angle)
        Goto Idle
    Idle:
        KGZ1 A 1
        KGZ1 A 1 A_SpawnItemEx("KeyGizmoFloatGreen", 0, 0, 60)
        KGZ1 A -1
        Stop
   }
}

Return to “Scripting”