Jump to the end of inactive on spawn

Tue Oct 26, 2021 5:54 am

I have a little scenery item (a mechanic's hand-held toobox) that inherits from SwitchableDecoration. As such, it can be opened or closed by activating/deactivating it (activating is open, deactivating is closed). This also allows me to place either the open or the closed version in a map by whether I set the dormant flag or not.

However, I have a minor problem with it. I have set it so that, if active, the item spawns and then skips to the end of the Active state sequence (without running through the opening animation) and sits there. Fine, that's what I want. However, if I want the closed (inactive) version to appear on a map, it spawns in its open position and then closes in the first few tics of the game. Not a huge issue but if the player start is near one of these decorations, the player can see and hear the toolbox closing.

Here is my code.

Code:
//Little hand-held toolbox
ACTOR ModelToolBoxHandHeld : SwitchableDecoration
{
   Radius 16
   Height 16
   +FLOORCLIP
   States
   {
   Spawn:
   POSS A 1
   goto Active+6
   Active:
   POSS F 2 A_StartSound("misc/ToolboxOpen1")
   POSS EDCBA 2
   POSS A -1
   Stop
   
   Inactive:
   POSS ABCD 2
   POSS E 2 A_StartSound("misc/ToolboxClose1")
   POSS F 2
   POSS F -1
   Stop
   }
}

How can I set this up so that it still behaves as it currently does if the item is not dormant but if the item is set to dormant when placed in the map, it will spawn and then go to the end of the Inactive state sequence, skipping out the closing animation and sound?

It's currently in DECORATE, but it doesn't have to be.

Re: Jump to the end of inactive on spawn

Tue Oct 26, 2021 6:18 am

Making another Actor with inverse logic? 8-)
Well, you can play with Args and make some checks/jumps in the first Spawn frame.

Send me this Actor.

Re: Jump to the end of inactive on spawn

Tue Oct 26, 2021 7:52 am

Twio choices: Either use a second actor or check one of the accessible spawn flags or args in the spawn state and initiate the same logic with another target state.
You can also do this without any state jumping voodoo by putting the 'Spawn' label directly before the state you want to see the actor in, to avoid any visual glitches with the first state's delay.

Re: Jump to the end of inactive on spawn

Tue Oct 26, 2021 8:51 am

OK, cool, thanks for the input. For no good reason really I was trying to do it all within the same actor but a second actor with reversed logic actually seems like the simplest solution.

Thanks again.

Re: Jump to the end of inactive on spawn

Tue Oct 26, 2021 2:56 pm

It can be done with one actor if you don't mind ZScript.

Code:
Class ModelToolBoxHandHeld : SwitchableDecoration
{
   Default
   {
      Radius 16;
      Height 16;
      +FLOORCLIP
   }

   States
   {
      Spawn:
         POSS A 1;
         Goto Active+6;
      Active:
         POSS F 2
         {
            If (bSTANDSTILL)
            {
               bSTANDSTILL = False;
               A_SetState("Inactive",8);
            }

            A_StartSound("misc/ToolboxOpen1");
         }
         POSS EDCBA 2;
         POSS A -1;
         Stop;
      Inactive:
         POSS A 1;
         POSS A 0
         {
            If (bSTANDSTILL)
            {
               bSTANDSTILL = False;
               A_SetState("Inactive",8);
            }
         }
         POSS ABCD 2;
         POSS E 2 A_StartSound("misc/ToolboxClose1");
         POSS F 2;
         POSS F -1;
         Stop;
   }

   Void A_SetState(StateLabel Label = "Ready", Int Offset = 0)
   {
      SetState(FindState(Label,False) + Offset,False);
   }
}

It took me a little while to figure out, it seems the map editor DORMANT flag is either not the same one as what can be set directly on the actor or it is unset sometime during map initialization for switchable decorations as the flag always returned false when checking for it. As a workaround, using the STANDSTILL flag will cause the tool box to go directly to the last state in when in "Inactive", then the flag is unchecked so that this only happens once. Use the DORMANT flag as well and the tool box will go directly to the last state in "Inactive" upon spawning.

EDIT:
Changed the above code so that the DORMANT flag is not needed.
Last edited by 22alpha22 on Tue Oct 26, 2021 4:01 pm, edited 2 times in total.

Re: Jump to the end of inactive on spawn

Tue Oct 26, 2021 3:48 pm

I did wonder if there was something weird about the map based dormant flag because I remember it giving me a similar problem some time ago with something else that I was trying to do - though I don't recall the exact details.

Thanks for the code. Zscript is absolutely fine so I'll give the above a try with the actor resources and the map. The only problem I foresee is me remembering to set STANDSTILL instead of DORMANT. :lol:

Re: Jump to the end of inactive on spawn

Tue Oct 26, 2021 6:22 pm

100% functional!

Code:
ACTOR ImpSwitch : SwitchableDecoration 101
{
Radius 16
Height 16
+FLOORCLIP
+USESPECIAL
Activation THINGSPEC_Switch | THINGSPEC_Activate
   
Var Int User_IsDead;
   
States
 {
 Spawn:
 TNT1 A 0 NoDelay
 {
 If(Args[0])
 {
 User_IsDead = 1; Return State("Dead"); } Else { User_IsDead = 0; Return State(""); }
 }
   
 Alive:
 TROO A 1
 Loop
   
 Dead:
 TROO M 1
 Loop
   
 ToDie:
 //Pass
 Active:
 TNT1 A 0
 {
 If(User_IsDead)
 {
 Return State("ToLive"); } Else { Return State(""); }
 }
 TNT1 A 0 A_PlaySound("imp/death")   
 TROO I 5
 TROO J 5
 TROO K 5
 TROO L 5 { User_IsDead = 1; }
 //Pass
 ActiveLoop:
 TROO M 1
 Loop
   
 ToLive:
 //Pass
 Inactive:
 TNT1 A 0 A_PlaySound("vile/raise")
 TNT1 A 0
 {
 If(!User_IsDead)
 {
 Return State("ToDie"); } Else { Return State(""); }
 }
 TROO MLKJ 5
 TROO I 5 { User_IsDead = 0; }
 //Pass
 InactiveLoop:
 TROO A 1
 Loop
  }
}


EnjaySwitch.pk3
You do not have the required permissions to view the files attached to this post.

Re: Jump to the end of inactive on spawn

Wed Oct 27, 2021 4:05 am

That's very cool - definitely does the job.

There is only one oddity that I have noticed - both Thing_Activate and Thing_Deactivate seem to have exactly the same effect on this actor. e.g. giving the imp on the left tid 1 and the one on the right tid 2 I ran the following scripts:
Code:
script 1 (void)
{
   Thing_Activate(1);
   Thing_Deactivate(2);
}

script 2 (void)
{
   Thing_Activate(2);
   Thing_Deactivate(1);
}

script 3 (void)
{
   Thing_Activate(2);
   Thing_Activate(1);
}

script 4 (void)
{
   Thing_Deactivate(2);
   Thing_Deactivate(1);
}


and it didn't matter which script I ran - they all just seem to toggle the condition of the imp each time it is run (in fact, I can run the same script over and over to toggle the imps back and forth even though the script is supposedly doing the same thing each time).

I haven't had a chance to dig into the code and figure out why this happens though.

Re: Jump to the end of inactive on spawn

Wed Oct 27, 2021 4:57 am

Use SetActorState function or ChangeActorFlag "UseSpecial" 1/0 to turn the Actor activable or unactivable.

Re: Jump to the end of inactive on spawn

Wed Oct 27, 2021 5:21 am

Understood. Thank you. :)