mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 07:57:58 +00:00
- fix handling of the global script in FraggleScript.
Depending on serialization order is not a good idea here, so now it's no longer stored as a parent in the main level script but explicitly checked for when looking for a variable.
This commit is contained in:
parent
4d98c10ea3
commit
11c453a71f
5 changed files with 25 additions and 22 deletions
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
/* includes ************************/
|
/* includes ************************/
|
||||||
#include "t_script.h"
|
#include "t_script.h"
|
||||||
|
#include "g_levellocals.h"
|
||||||
|
|
||||||
|
|
||||||
#define evaluate_leftnright(a, b, c) {\
|
#define evaluate_leftnright(a, b, c) {\
|
||||||
|
@ -84,7 +85,7 @@ void FParser::OPequals(svalue_t &result, int start, int n, int stop)
|
||||||
{
|
{
|
||||||
DFsVariable *var;
|
DFsVariable *var;
|
||||||
|
|
||||||
var = Script->FindVariable(Tokens[start]);
|
var = Script->FindVariable(Tokens[start], Level->FraggleScriptThinker->GlobalScript);
|
||||||
|
|
||||||
if(var)
|
if(var)
|
||||||
{
|
{
|
||||||
|
@ -478,7 +479,7 @@ void FParser::OPincrement(svalue_t &result, int start, int n, int stop)
|
||||||
{
|
{
|
||||||
DFsVariable *var;
|
DFsVariable *var;
|
||||||
|
|
||||||
var = Script->FindVariable(Tokens[stop]);
|
var = Script->FindVariable(Tokens[stop], Level->FraggleScriptThinker->GlobalScript);
|
||||||
if(!var)
|
if(!var)
|
||||||
{
|
{
|
||||||
script_error("unknown variable '%s'\n", Tokens[stop]);
|
script_error("unknown variable '%s'\n", Tokens[stop]);
|
||||||
|
@ -503,7 +504,7 @@ void FParser::OPincrement(svalue_t &result, int start, int n, int stop)
|
||||||
svalue_t newvalue;
|
svalue_t newvalue;
|
||||||
DFsVariable *var;
|
DFsVariable *var;
|
||||||
|
|
||||||
var = Script->FindVariable(Tokens[start]);
|
var = Script->FindVariable(Tokens[start], Level->FraggleScriptThinker->GlobalScript);
|
||||||
if(!var)
|
if(!var)
|
||||||
{
|
{
|
||||||
script_error("unknown variable '%s'\n", Tokens[start]);
|
script_error("unknown variable '%s'\n", Tokens[start]);
|
||||||
|
@ -541,7 +542,7 @@ void FParser::OPdecrement(svalue_t &result, int start, int n, int stop)
|
||||||
{
|
{
|
||||||
DFsVariable *var;
|
DFsVariable *var;
|
||||||
|
|
||||||
var = Script->FindVariable(Tokens[stop]);
|
var = Script->FindVariable(Tokens[stop], Level->FraggleScriptThinker->GlobalScript);
|
||||||
if(!var)
|
if(!var)
|
||||||
{
|
{
|
||||||
script_error("unknown variable '%s'\n", Tokens[stop]);
|
script_error("unknown variable '%s'\n", Tokens[stop]);
|
||||||
|
@ -567,7 +568,7 @@ void FParser::OPdecrement(svalue_t &result, int start, int n, int stop)
|
||||||
svalue_t newvalue;
|
svalue_t newvalue;
|
||||||
DFsVariable *var;
|
DFsVariable *var;
|
||||||
|
|
||||||
var = Script->FindVariable(Tokens[start]);
|
var = Script->FindVariable(Tokens[start], Level->FraggleScriptThinker->GlobalScript);
|
||||||
if(!var)
|
if(!var)
|
||||||
{
|
{
|
||||||
script_error("unknown variable '%s'\n", Tokens[start]);
|
script_error("unknown variable '%s'\n", Tokens[start]);
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "t_script.h"
|
#include "t_script.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
|
#include "g_levellocals.h"""
|
||||||
|
|
||||||
CVAR(Bool, script_debug, false, 0)
|
CVAR(Bool, script_debug, false, 0)
|
||||||
|
|
||||||
|
@ -561,7 +561,7 @@ void FParser::SimpleEvaluate(svalue_t &returnvar, int n)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case name_:
|
case name_:
|
||||||
var = Script->FindVariable(Tokens[n]);
|
var = Script->FindVariable(Tokens[n], Level->FraggleScriptThinker->GlobalScript);
|
||||||
if(!var)
|
if(!var)
|
||||||
{
|
{
|
||||||
script_error("unknown variable '%s'\n", Tokens[n]);
|
script_error("unknown variable '%s'\n", Tokens[n]);
|
||||||
|
|
|
@ -176,8 +176,6 @@ void DFsScript::OnDestroy()
|
||||||
void DFsScript::Serialize(FSerializer &arc)
|
void DFsScript::Serialize(FSerializer &arc)
|
||||||
{
|
{
|
||||||
Super::Serialize(arc);
|
Super::Serialize(arc);
|
||||||
// don't save a reference to the global script, which contains unserializable data.
|
|
||||||
if (parent == level.FraggleScriptThinker->GlobalScript) parent = nullptr;
|
|
||||||
|
|
||||||
arc("data", data)
|
arc("data", data)
|
||||||
("scriptnum", scriptnum)
|
("scriptnum", scriptnum)
|
||||||
|
@ -188,8 +186,6 @@ void DFsScript::Serialize(FSerializer &arc)
|
||||||
.Array("sections", sections, SECTIONSLOTS)
|
.Array("sections", sections, SECTIONSLOTS)
|
||||||
.Array("variables", variables, VARIABLESLOTS)
|
.Array("variables", variables, VARIABLESLOTS)
|
||||||
.Array("children", children, MAXSCRIPTS);
|
.Array("children", children, MAXSCRIPTS);
|
||||||
|
|
||||||
if (parent == nullptr) parent = level.FraggleScriptThinker->GlobalScript;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -200,7 +196,7 @@ void DFsScript::Serialize(FSerializer &arc)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void DFsScript::ParseScript(char *position)
|
void DFsScript::ParseScript(char *position, AActor **pTrigger)
|
||||||
{
|
{
|
||||||
if (position == nullptr)
|
if (position == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -215,7 +211,7 @@ void DFsScript::ParseScript(char *position)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
level.FraggleScriptThinker->trigger_obj = trigger; // set trigger
|
*pTrigger = trigger; // set trigger variable.
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -387,7 +383,7 @@ void DFraggleThinker::Construct()
|
||||||
RunningScripts = Create<DRunningScript>();
|
RunningScripts = Create<DRunningScript>();
|
||||||
GC::WriteBarrier(this, RunningScripts);
|
GC::WriteBarrier(this, RunningScripts);
|
||||||
LevelScript = Create<DFsScript>();
|
LevelScript = Create<DFsScript>();
|
||||||
LevelScript->parent = GlobalScript;
|
LevelScript->parent = nullptr;
|
||||||
GC::WriteBarrier(this, LevelScript);
|
GC::WriteBarrier(this, LevelScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,10 +461,10 @@ bool DFraggleThinker::wait_finished(DRunningScript *script)
|
||||||
case wt_tagwait:
|
case wt_tagwait:
|
||||||
{
|
{
|
||||||
int secnum;
|
int secnum;
|
||||||
auto itr = level.GetSectorTagIterator(script->wait_data);
|
auto itr = Level->GetSectorTagIterator(script->wait_data);
|
||||||
while ((secnum = itr.Next()) >= 0)
|
while ((secnum = itr.Next()) >= 0)
|
||||||
{
|
{
|
||||||
sector_t *sec = &level.sectors[secnum];
|
sector_t *sec = &Level->sectors[secnum];
|
||||||
if(sec->floordata || sec->ceilingdata || sec->lightingdata)
|
if(sec->floordata || sec->ceilingdata || sec->lightingdata)
|
||||||
return false; // not finished
|
return false; // not finished
|
||||||
}
|
}
|
||||||
|
@ -532,7 +528,7 @@ void DFraggleThinker::Tick()
|
||||||
next = current->next; // save before freeing
|
next = current->next; // save before freeing
|
||||||
|
|
||||||
// continue the script
|
// continue the script
|
||||||
current->script->ParseScript (current->script->data + current->save_point);
|
current->script->ParseScript (current->script->data + current->save_point, &trigger_obj);
|
||||||
|
|
||||||
// free
|
// free
|
||||||
current->Destroy();
|
current->Destroy();
|
||||||
|
@ -623,7 +619,7 @@ void T_PreprocessScripts(FLevelLocals *Level)
|
||||||
th->LevelScript->trigger = players[0].mo;
|
th->LevelScript->trigger = players[0].mo;
|
||||||
|
|
||||||
th->LevelScript->Preprocess();
|
th->LevelScript->Preprocess();
|
||||||
th->LevelScript->ParseScript();
|
th->LevelScript->ParseScript(nullptr, &th->trigger_obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -341,7 +341,7 @@ public:
|
||||||
void NewFunction(const char *name, void (FParser::*handler)());
|
void NewFunction(const char *name, void (FParser::*handler)());
|
||||||
|
|
||||||
DFsVariable *VariableForName(const char *name);
|
DFsVariable *VariableForName(const char *name);
|
||||||
DFsVariable *FindVariable(const char *name);
|
DFsVariable *FindVariable(const char *name, DFsScript *global);
|
||||||
void ClearVariables(bool complete= false);
|
void ClearVariables(bool complete= false);
|
||||||
DFsVariable *NewLabel(char *labelptr);
|
DFsVariable *NewLabel(char *labelptr);
|
||||||
char *LabelValue(const svalue_t &v);
|
char *LabelValue(const svalue_t &v);
|
||||||
|
@ -363,7 +363,7 @@ public:
|
||||||
void DryRunScript();
|
void DryRunScript();
|
||||||
void Preprocess();
|
void Preprocess();
|
||||||
void ParseInclude(char *lumpname);
|
void ParseInclude(char *lumpname);
|
||||||
void ParseScript(char *rover = NULL);
|
void ParseScript(char *rover, AActor **pTrigger);
|
||||||
void ParseData(char *rover, char *data, char *end);
|
void ParseData(char *rover, char *data, char *end);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -364,7 +364,7 @@ DFsVariable *DFsScript::VariableForName(const char *name)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
DFsVariable *DFsScript::FindVariable(const char *name)
|
DFsVariable *DFsScript::FindVariable(const char *name, DFsScript *GlobalScript)
|
||||||
{
|
{
|
||||||
DFsVariable *var;
|
DFsVariable *var;
|
||||||
DFsScript *current = this;
|
DFsScript *current = this;
|
||||||
|
@ -374,7 +374,13 @@ DFsVariable *DFsScript::FindVariable(const char *name)
|
||||||
// check this script
|
// check this script
|
||||||
if ((var = current->VariableForName(name)))
|
if ((var = current->VariableForName(name)))
|
||||||
return var;
|
return var;
|
||||||
current = current->parent; // try the parent of this one
|
|
||||||
|
// Since the global script cannot be serialized, we cannot store a pointer to it, because this cannot be safely restored during deserialization.
|
||||||
|
// To compensate we need to check the relationship explicitly here.
|
||||||
|
if (current->parent == nullptr && current != GlobalScript)
|
||||||
|
current = GlobalScript;
|
||||||
|
else
|
||||||
|
current = current->parent; // try the parent of this one
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL; // no variable
|
return NULL; // no variable
|
||||||
|
|
Loading…
Reference in a new issue