I created a switchable decoration. It needs to stay synchronized with other switchable decorations, so it's activate() and deactivate() methods call level.executespecial() to activate and deactivate it's "child" associations. I want it to start out deactivated, so I give it the dormant flag. Probelm is that when the level loads, not all decorations are synchronized - some of it's children are dormant, while others are not. Some troubleshooting has led me to believe that internally there is a if (bDormant) Deactivate(null) line called in BeginPlay(). The reason my decorations are out of sync is that some of the children aren't loaded/placed on the map when the BeginPlay() executes, so they're not getting the deactivate() call.
My suggestion is to move that call from BeginPlay() to PostBeginPlay(). Or would that break other things?
The workaround is obviously simple, I don't use the bDormant bolean, I create my own called inactive, and throw a if (inactive) deactivate(null) into PostBeginPlay()
dormant deactivate should be PostBeginPlay?
Moderator: GZDoom Developers
Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49225
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: dormant deactivate should be PostBeginPlay?
Please post a piece of demonstration. This is too abstract for a bug report.
- Sir Robin
- Posts: 537
- Joined: Wed Dec 22, 2021 7:02 pm
- Graphics Processor: Intel (Modern GZDoom)
- Location: Medellin, Colombia
Re: dormant deactivate should be PostBeginPlay?
Excuse me, let me simplify. Consider this code:
Create a new map, with player 1 start
Place a child, set TID 1
Place a master, set arg0 1
Place another child, set TID 1
run the map
master is dormant, so the deactivate fires immediately, tic 0
special "deactivate thing" is called for TID 1
One child reports deactivation
The other child never does
I believe because the master deactivation was fired before the second child was loaded in the map.
Therefore my conslusion is that the dormant deactivation is called from BeginPlay instead of PostBeginPlay
My suggestion is to move it into PostBeginPlay
Code: Select all
class SwitchedMaster : actor
{
default
{
//$Arg0 Child TID
//$Arg0Type 14
+Dormant;
}
override void deactivate(actor activator)
{
console.printf("["..level.time.."]["..GetCharacterName().."] Deactivated by "..(activator ? activator.GetCharacterName() : "[NULL]"));
Level.ExecuteSpecial(131, activator, null, false, args[0], 0, 0, 0, 0);
}
}
class SwitchedChild : actor
{
override void deactivate(actor activator)
{
console.printf("["..level.time.."]["..GetCharacterName().."] Deactivated by "..(activator ? activator.GetCharacterName() : "[NULL]"));
}
}
Place a child, set TID 1
Place a master, set arg0 1
Place another child, set TID 1
run the map
master is dormant, so the deactivate fires immediately, tic 0
special "deactivate thing" is called for TID 1
One child reports deactivation
The other child never does
I believe because the master deactivation was fired before the second child was loaded in the map.
Therefore my conslusion is that the dormant deactivation is called from BeginPlay instead of PostBeginPlay
My suggestion is to move it into PostBeginPlay
-
- Posts: 256
- Joined: Mon Jan 09, 2023 2:02 am
- Graphics Processor: nVidia (Modern GZDoom)
Re: dormant deactivate should be PostBeginPlay?
Instead of changing the engine, how about changing your setup?
You are correct about order of calls, so you simply cannot do it this way. You should override PostBeginPlay yourself and in there do the necessary things based on the master's state.
What you are doing here looks like an edge case that isn't worth sacrificing established behavior.
- Sir Robin
- Posts: 537
- Joined: Wed Dec 22, 2021 7:02 pm
- Graphics Processor: Intel (Modern GZDoom)
- Location: Medellin, Colombia
Re: dormant deactivate should be PostBeginPlay?
That's why I posted it as a question - Is this behaviour undesired? If so is it worth fixing? If so does it break other established behaivor? Those are questions for the dev team, above my paygrade, I'm just bringing the quirk to their attention.
Yes I can work around this quirk, as mentioned in my original post. I'm posting here in the hopes that someone else who finds this quirk, assuming that it is not changed in the engine, will be able to search and find this thread and not spend the time trying to figure out why their code isn't working.
Yes I can work around this quirk, as mentioned in my original post. I'm posting here in the hopes that someone else who finds this quirk, assuming that it is not changed in the engine, will be able to search and find this thread and not spend the time trying to figure out why their code isn't working.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49225
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: dormant deactivate should be PostBeginPlay?
Since you found out yourself why your setup doesn't work it should be obvious that you have to find an alternative approach.
The initial deactivate call runs at a time when not all actors are present so you cannot use it to do stuff that affects other actors.
No, I won't consider changing this. Who knows how many mods depend on these actors starting fully deactivated that may break by the change?
The initial deactivate call runs at a time when not all actors are present so you cannot use it to do stuff that affects other actors.
No, I won't consider changing this. Who knows how many mods depend on these actors starting fully deactivated that may break by the change?