You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The trigger class CCreatureTrigger has an EvaluateAll attribute. The intent is to fire the trigger only when all the creatures listed in the trigger have died. (The more general CCreatureTrigger usage also supports other creature events.)
In the original levels, EvaluateAll is used in only one place: in Industrial Jungle right after the waterfall, at the entrance of the valley.
When the raptor from the fighting ground dies, it will cause another raptor to appear at spawn point 1.
When the raptor from the fighting ground, the raptor from spawn point 1 and the albertosaurus are all dead, it is supposed to cause two more raptors to appear around spawn point 2. This event is the CCreatureTrigger in question with EvaluateAll.
The type of death does not matter; the dinosaurs can kill each other.
The problem is that in the situation above, with the current engine code and the level script as-is, the EvaluateAll attribute is unused. The trigger fires when any one of the three dinosaurs dies.
The are-all-dinos-dead check happens in CCreatureTrigger::bEvaluateNow(), which is never called.
To use EvaluateAll, the trigger would require a FireExpression as an additional condition to be checked when attempting to trigger. In T-Script, the expression would have to be a "query expression", starting with @. This would cause CCreatureTrigger::bEvaluateNow() to be called. Such FireExpressions are also possible for other trigger types and definitely exist in the level script code.
One might propose to auto-insert the the FireExpression by adding these lines near the end of the CCreatureTrigger constructor:
if (bEvaluateAll && !peeFireExpression) {
peeFireExpression = new CExpressionEvaluate();
peeFireExpression->AddExpressionOperand(this, true);
}
But it does not work. The created expression is supposed to have the state EELEMENT_STATE_QUERY (4), but when the check happens in CExpressionEvaluate::EvaluateExpression(), it has EELEMENT_STATE_NOT_FIRED (0).
And finally, if one hacks around this problem as well and finally gets to the call of CCreatureTrigger::bEvaluateNow(), it will cause the game to crash. The function searches for the dino entities in the word data, but the query fails for all three dinos. Because there is no nullptr check for the search result, but merely an Assert, this will cause a crash.
Question to resolve:
Are self-referential query FireExpressions, as required here, possible in T-Script?
Why does the auto-insert snippet above not work? Why does the state get lost/changed?
How can CCreatureTrigger::bEvaluateNow() be repaired? How are the dinosaurs and their state supposed to be queried here?
The solution must also be serializable (pcSave and pcLoad). That means if the player creates a savefile with one or two of the dinos already dead, then loads that save, the trigger must still work when the rest of the dinos die.
The above still holds when an alternative solution without FireExpressions is implemented.
The text was updated successfully, but these errors were encountered:
The trigger class
CCreatureTrigger
has an EvaluateAll attribute. The intent is to fire the trigger only when all the creatures listed in the trigger have died. (The more generalCCreatureTrigger
usage also supports other creature events.)In the original levels, EvaluateAll is used in only one place: in Industrial Jungle right after the waterfall, at the entrance of the valley.
![TPass050](https://user-images.githubusercontent.com/5839584/113518614-b5e8f980-9587-11eb-872a-2b61fb05bd58.png)
The type of death does not matter; the dinosaurs can kill each other.
The problem is that in the situation above, with the current engine code and the level script as-is, the
EvaluateAll
attribute is unused. The trigger fires when any one of the three dinosaurs dies.The are-all-dinos-dead check happens in
CCreatureTrigger::bEvaluateNow()
, which is never called.To use EvaluateAll, the trigger would require a
FireExpression
as an additional condition to be checked when attempting to trigger. In T-Script, the expression would have to be a "query expression", starting with @. This would causeCCreatureTrigger::bEvaluateNow()
to be called. Such FireExpressions are also possible for other trigger types and definitely exist in the level script code.One might propose to auto-insert the the FireExpression by adding these lines near the end of the
CCreatureTrigger
constructor:But it does not work. The created expression is supposed to have the state
EELEMENT_STATE_QUERY
(4), but when the check happens inCExpressionEvaluate::EvaluateExpression()
, it hasEELEMENT_STATE_NOT_FIRED
(0).And finally, if one hacks around this problem as well and finally gets to the call of
CCreatureTrigger::bEvaluateNow()
, it will cause the game to crash. The function searches for the dino entities in the word data, but the query fails for all three dinos. Because there is no nullptr check for the search result, but merely anAssert
, this will cause a crash.Question to resolve:
FireExpressions
, as required here, possible in T-Script?CCreatureTrigger::bEvaluateNow()
be repaired? How are the dinosaurs and their state supposed to be queried here?pcSave
andpcLoad
). That means if the player creates a savefile with one or two of the dinos already dead, then loads that save, the trigger must still work when the rest of the dinos die.FireExpressions
is implemented.The text was updated successfully, but these errors were encountered: