[Scummvm-git-logs] scummvm master -> 7eee4e7b2c4850485efbc11787f712df14adae2b

elasota noreply at scummvm.org
Wed Oct 26 03:08:23 UTC 2022


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
6a0f8df3dd MTROPOLIS: Stub out set modifier.
7eee4e7b2c MTROPOLIS: Split IncomingData and VarReference cases out of DynamicValue to a new DynamicValueSource type.


Commit: 6a0f8df3ddf753e0e9fa1ccd535717361cf086dc
    https://github.com/scummvm/scummvm/commit/6a0f8df3ddf753e0e9fa1ccd535717361cf086dc
Author: elasota (ejlasota at gmail.com)
Date: 2022-10-25T23:04:56-04:00

Commit Message:
MTROPOLIS: Stub out set modifier.

Changed paths:
    engines/mtropolis/modifiers.cpp
    engines/mtropolis/modifiers.h


diff --git a/engines/mtropolis/modifiers.cpp b/engines/mtropolis/modifiers.cpp
index 86624f6f03c..0e26a1a7f6b 100644
--- a/engines/mtropolis/modifiers.cpp
+++ b/engines/mtropolis/modifiers.cpp
@@ -497,6 +497,25 @@ bool SetModifier::load(ModifierLoaderContext &context, const Data::SetModifier &
 	return true;
 }
 
+bool SetModifier::respondsToEvent(const Event &evt) const {
+	if (_executeWhen.respondsTo(evt))
+		return true;
+
+	return false;
+}
+
+VThreadState SetModifier::consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
+	if (_executeWhen.respondsTo(msg->getEvent())) {
+#ifdef MTROPOLIS_DEBUG_ENABLE
+		if (Debugger *debugger = runtime->debugGetDebugger())
+			debugger->notifyFmt(kDebugSeverityError, "Set modifier is not yet implemented");
+#endif
+		warning("Set modifier is not yet implemented!");
+		return kVThreadReturn;
+	}
+	return kVThreadReturn;
+}
+
 Common::SharedPtr<Modifier> SetModifier::shallowClone() const {
 	return Common::SharedPtr<Modifier>(new SetModifier(*this));
 }
diff --git a/engines/mtropolis/modifiers.h b/engines/mtropolis/modifiers.h
index ea88255ea07..5d2190ac3f2 100644
--- a/engines/mtropolis/modifiers.h
+++ b/engines/mtropolis/modifiers.h
@@ -235,6 +235,9 @@ class SetModifier : public Modifier {
 public:
 	bool load(ModifierLoaderContext &context, const Data::SetModifier &data);
 
+	bool respondsToEvent(const Event &evt) const override;
+	VThreadState consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) override;
+
 	void disable(Runtime *runtime) override {}
 
 #ifdef MTROPOLIS_DEBUG_ENABLE


Commit: 7eee4e7b2c4850485efbc11787f712df14adae2b
    https://github.com/scummvm/scummvm/commit/7eee4e7b2c4850485efbc11787f712df14adae2b
Author: elasota (ejlasota at gmail.com)
Date: 2022-10-25T23:05:00-04:00

Commit Message:
MTROPOLIS: Split IncomingData and VarReference cases out of DynamicValue to a new DynamicValueSource type.

Changed paths:
    engines/mtropolis/hacks.cpp
    engines/mtropolis/miniscript.cpp
    engines/mtropolis/modifiers.cpp
    engines/mtropolis/modifiers.h
    engines/mtropolis/plugin/standard.cpp
    engines/mtropolis/plugin/standard.h
    engines/mtropolis/runtime.cpp
    engines/mtropolis/runtime.h


diff --git a/engines/mtropolis/hacks.cpp b/engines/mtropolis/hacks.cpp
index a250607d4fe..65c226709e0 100644
--- a/engines/mtropolis/hacks.cpp
+++ b/engines/mtropolis/hacks.cpp
@@ -790,7 +790,7 @@ void ObsidianAutoSaveVarsState::resyncAllVars(Runtime *runtime) {
 		const VariableModifier *var = findVar(runtime, it->_key);
 		if (var) {
 			DynamicValue varValue;
-			var->varGetValue(nullptr, varValue);
+			var->varGetValue(varValue);
 			assert(varValue.getType() == DynamicValueTypes::kBoolean);
 
 			it->_value = varValue.getBool();
@@ -852,7 +852,7 @@ void ObsidianAutoSaveSceneTransitionHooks::onSceneTransitionEnded(Runtime *runti
 			const VariableModifier *var = _varsState->findVar(runtime, varName);
 			if (var) {
 				DynamicValue varValue;
-				var->varGetValue(nullptr, varValue);
+				var->varGetValue(varValue);
 				assert(varValue.getType() == DynamicValueTypes::kBoolean);
 
 				passedLatchTest = varValue.getBool();
@@ -983,7 +983,7 @@ bool ObsidianSaveLoadMechanism::canSaveNow(Runtime *runtime) {
 		return false;
 
 	DynamicValue bEscValue;
-	static_cast<VariableModifier *>(bEscVar)->varGetValue(nullptr, bEscValue);
+	static_cast<VariableModifier *>(bEscVar)->varGetValue(bEscValue);
 
 	if (bEscValue.getType() != DynamicValueTypes::kBoolean || !bEscValue.getBool())
 		return false;
diff --git a/engines/mtropolis/miniscript.cpp b/engines/mtropolis/miniscript.cpp
index efd424f1ad8..3940b1f49b9 100644
--- a/engines/mtropolis/miniscript.cpp
+++ b/engines/mtropolis/miniscript.cpp
@@ -1916,7 +1916,7 @@ MiniscriptInstructionOutcome MiniscriptThread::dereferenceRValue(size_t offset,
 			if (obj && obj->isModifier()) {
 				const Modifier *modifier = static_cast<const Modifier *>(obj.get());
 				if (modifier->isVariable()) {
-					static_cast<const VariableModifier *>(modifier)->varGetValue(this, stackValue.value);
+					static_cast<const VariableModifier *>(modifier)->varGetValue(stackValue.value);
 				}
 			}
 		} break;
@@ -2033,7 +2033,7 @@ MiniscriptInstructionOutcome MiniscriptThread::tryLoadVariable(MiniscriptStackVa
 		Common::SharedPtr<RuntimeObject> obj = stackValue.value.getObject().object.lock();
 		if (obj && obj->isModifier() && static_cast<Modifier *>(obj.get())->isVariable()) {
 			VariableModifier *varMod = static_cast<VariableModifier *>(obj.get());
-			varMod->varGetValue(this, stackValue.value);
+			varMod->varGetValue(stackValue.value);
 		}
 	}
 
diff --git a/engines/mtropolis/modifiers.cpp b/engines/mtropolis/modifiers.cpp
index 0e26a1a7f6b..be15549f51d 100644
--- a/engines/mtropolis/modifiers.cpp
+++ b/engines/mtropolis/modifiers.cpp
@@ -378,7 +378,7 @@ bool SaveAndRestoreModifier::respondsToEvent(const Event &evt) const {
 }
 
 VThreadState SaveAndRestoreModifier::consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
-	if (_saveOrRestoreValue.getType() != DynamicValueTypes::kVariableReference) {
+	if (_saveOrRestoreValue.getSourceType() != DynamicValueSourceTypes::kVariableReference) {
 		warning("Save/restore failed, don't know how to use something that isn't a var reference");
 		return kVThreadError;
 	}
@@ -964,29 +964,7 @@ bool VectorMotionModifier::respondsToEvent(const Event &evt) const {
 
 VThreadState VectorMotionModifier::consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
 	if (_enableWhen.respondsTo(msg->getEvent())) {
-		DynamicValue vec;
-		if (_vec.getType() == DynamicValueTypes::kIncomingData) {
-			vec = msg->getValue();
-		} else if (!_vecVar.expired()) {
-			Modifier *modifier = _vecVar.lock().get();
-
-			if (!modifier->isVariable()) {
-#ifdef MTROPOLIS_DEBUG_ENABLE
-				if (Debugger *debugger = runtime->debugGetDebugger())
-					debugger->notify(kDebugSeverityError, "Vector variable reference was to a non-variable");
-#endif
-				return kVThreadError;
-			}
-
-			VariableModifier *varModifier = static_cast<VariableModifier *>(modifier);
-			varModifier->varGetValue(nullptr, vec);
-		} else {
-#ifdef MTROPOLIS_DEBUG_ENABLE
-			if (Debugger *debugger = runtime->debugGetDebugger())
-				debugger->notify(kDebugSeverityError, "Vector variable reference wasn't resolved");
-#endif
-			return kVThreadError;
-		}
+		DynamicValue vec = _vec.produceValue(msg->getValue());
 
 		if (vec.getType() != DynamicValueTypes::kVector) {
 #ifdef MTROPOLIS_DEBUG_ENABLE
@@ -1025,14 +1003,10 @@ void VectorMotionModifier::trigger(Runtime *runtime) {
 	uint64 currentTime = runtime->getPlayTime();
 	_scheduledEvent = runtime->getScheduler().scheduleMethod<VectorMotionModifier, &VectorMotionModifier::trigger>(currentTime + 1, this);
 
-	Modifier *vecSrcModifier = _vecVar.lock().get();
-
 	// Variable-sourced motion is continuously updated and doesn't need to be re-triggered.
 	// The Pong minigame in Obsidian's Bureau chapter depends on this.
-	if (vecSrcModifier && vecSrcModifier->isVariable()) {
-		DynamicValue vec;
-		VariableModifier *varModifier = static_cast<VariableModifier *>(vecSrcModifier);
-		varModifier->varGetValue(nullptr, vec);
+	if (_vec.getSourceType() == DynamicValueSourceTypes::kVariableReference) {
+		DynamicValue vec = _vec.produceValue(DynamicValue());
 
 		if (vec.getType() == DynamicValueTypes::kVector)
 			_resolvedVector = vec.getVector();
@@ -1081,21 +1055,11 @@ const char *VectorMotionModifier::getDefaultName() const {
 }
 
 void VectorMotionModifier::linkInternalReferences(ObjectLinkingScope *scope) {
-	if (_vec.getType() == DynamicValueTypes::kVariableReference) {
-		const VarReference &varRef = _vec.getVarReference();
-		Common::WeakPtr<RuntimeObject> objRef = scope->resolve(varRef.guid, varRef.source, false);
-
-		RuntimeObject *obj = objRef.lock().get();
-		if (obj == nullptr || !obj->isModifier()) {
-			warning("Vector motion modifier source was set to a variable, but the variable reference was invalid");
-		} else {
-			_vecVar = objRef.staticCast<Modifier>();
-		}
-	}
+	_vec.linkInternalReferences(scope);
 }
 
 void VectorMotionModifier::visitInternalReferences(IStructuralReferenceVisitor* visitor) {
-	visitor->visitWeakModifierRef(_vecVar);
+	_vec.visitInternalReferences(visitor);
 }
 
 bool SceneTransitionModifier::load(ModifierLoaderContext &context, const Data::SceneTransitionModifier &data) {
@@ -2407,7 +2371,7 @@ bool BooleanVariableModifier::varSetValue(MiniscriptThread *thread, const Dynami
 	return true;
 }
 
-void BooleanVariableModifier::varGetValue(MiniscriptThread *thread, DynamicValue &dest) const {
+void BooleanVariableModifier::varGetValue(DynamicValue &dest) const {
 	dest.setBool(_value);
 }
 
@@ -2481,7 +2445,7 @@ bool IntegerVariableModifier::varSetValue(MiniscriptThread *thread, const Dynami
 	return true;
 }
 
-void IntegerVariableModifier::varGetValue(MiniscriptThread *thread, DynamicValue &dest) const {
+void IntegerVariableModifier::varGetValue(DynamicValue &dest) const {
 	dest.setInt(_value);
 }
 
@@ -2545,7 +2509,7 @@ bool IntegerRangeVariableModifier::varSetValue(MiniscriptThread *thread, const D
 	return true;
 }
 
-void IntegerRangeVariableModifier::varGetValue(MiniscriptThread *thread, DynamicValue &dest) const {
+void IntegerRangeVariableModifier::varGetValue(DynamicValue &dest) const {
 	dest.setIntRange(_range);
 }
 
@@ -2635,7 +2599,7 @@ bool VectorVariableModifier::varSetValue(MiniscriptThread *thread, const Dynamic
 	return true;
 }
 
-void VectorVariableModifier::varGetValue(MiniscriptThread *thread, DynamicValue &dest) const {
+void VectorVariableModifier::varGetValue(DynamicValue &dest) const {
 	dest.setVector(_vector);
 }
 
@@ -2725,7 +2689,7 @@ bool PointVariableModifier::varSetValue(MiniscriptThread *thread, const DynamicV
 	return true;
 }
 
-void PointVariableModifier::varGetValue(MiniscriptThread *thread, DynamicValue &dest) const {
+void PointVariableModifier::varGetValue(DynamicValue &dest) const {
 	dest.setPoint(_value);
 }
 
@@ -2821,7 +2785,7 @@ bool FloatingPointVariableModifier::varSetValue(MiniscriptThread *thread, const
 	return true;
 }
 
-void FloatingPointVariableModifier::varGetValue(MiniscriptThread *thread, DynamicValue &dest) const {
+void FloatingPointVariableModifier::varGetValue(DynamicValue &dest) const {
 	dest.setFloat(_value);
 }
 
@@ -2884,7 +2848,7 @@ bool StringVariableModifier::varSetValue(MiniscriptThread *thread, const Dynamic
 	return true;
 }
 
-void StringVariableModifier::varGetValue(MiniscriptThread *thread, DynamicValue &dest) const {
+void StringVariableModifier::varGetValue(DynamicValue &dest) const {
 	dest.setString(_value);
 }
 
@@ -2976,7 +2940,7 @@ bool ObjectReferenceVariableModifierV1::varSetValue(MiniscriptThread *thread, co
 	return true;
 }
 
-void ObjectReferenceVariableModifierV1::varGetValue(MiniscriptThread *thread, DynamicValue &dest) const {
+void ObjectReferenceVariableModifierV1::varGetValue(DynamicValue &dest) const {
 	if (_value.expired())
 		dest.clear();
 	else
diff --git a/engines/mtropolis/modifiers.h b/engines/mtropolis/modifiers.h
index 5d2190ac3f2..3a70bea1819 100644
--- a/engines/mtropolis/modifiers.h
+++ b/engines/mtropolis/modifiers.h
@@ -200,7 +200,7 @@ private:
 	Event _saveWhen;
 	Event _restoreWhen;
 
-	DynamicValue _saveOrRestoreValue;
+	DynamicValueSource _saveOrRestoreValue;
 
 	Common::String _filePath;
 	Common::String _fileName;
@@ -249,8 +249,8 @@ private:
 	const char *getDefaultName() const override;
 
 	Event _executeWhen;
-	DynamicValue _source;
-	DynamicValue _target;
+	DynamicValueSource _source;
+	DynamicValueSource _target;
 };
 
 class AliasModifier : public Modifier {
@@ -439,8 +439,7 @@ private:
 	Event _enableWhen;
 	Event _disableWhen;
 
-	DynamicValue _vec;
-	Common::WeakPtr<Modifier> _vecVar;
+	DynamicValueSource _vec;
 
 	AngleMagVector _resolvedVector;
 	uint16 _subpixelX;
@@ -943,7 +942,7 @@ public:
 	Common::SharedPtr<ModifierSaveLoad> getSaveLoad() override;
 
 	bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) override;
-	void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const override;
+	void varGetValue(DynamicValue &dest) const override;
 
 #ifdef MTROPOLIS_DEBUG_ENABLE
 	const char *debugGetTypeName() const override { return "Boolean Variable Modifier"; }
@@ -980,7 +979,7 @@ public:
 	Common::SharedPtr<ModifierSaveLoad> getSaveLoad() override;
 
 	bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) override;
-	void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const override;
+	void varGetValue(DynamicValue &dest) const override;
 
 #ifdef MTROPOLIS_DEBUG_ENABLE
 	const char *debugGetTypeName() const override { return "Integer Variable Modifier"; }
@@ -1015,7 +1014,7 @@ public:
 	Common::SharedPtr<ModifierSaveLoad> getSaveLoad() override;
 
 	bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) override;
-	void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const override;
+	void varGetValue(DynamicValue &dest) const override;
 
 	bool readAttribute(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib) override;
 	MiniscriptInstructionOutcome writeRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &result, const Common::String &attrib) override;
@@ -1053,7 +1052,7 @@ public:
 	Common::SharedPtr<ModifierSaveLoad> getSaveLoad() override;
 
 	bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) override;
-	void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const override;
+	void varGetValue(DynamicValue &dest) const override;
 
 	bool readAttribute(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib) override;
 	MiniscriptInstructionOutcome writeRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &result, const Common::String &attrib) override;
@@ -1091,7 +1090,7 @@ public:
 	Common::SharedPtr<ModifierSaveLoad> getSaveLoad() override;
 
 	bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) override;
-	void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const override;
+	void varGetValue(DynamicValue &dest) const override;
 
 	bool readAttribute(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib) override;
 	MiniscriptInstructionOutcome writeRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &writeProxy, const Common::String &attrib) override;
@@ -1131,7 +1130,7 @@ public:
 	Common::SharedPtr<ModifierSaveLoad> getSaveLoad() override;
 
 	bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) override;
-	void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const override;
+	void varGetValue(DynamicValue &dest) const override;
 
 #ifdef MTROPOLIS_DEBUG_ENABLE
 	const char *debugGetTypeName() const override { return "Floating Point Variable Modifier"; }
@@ -1166,7 +1165,7 @@ public:
 	Common::SharedPtr<ModifierSaveLoad> getSaveLoad() override;
 
 	bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) override;
-	void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const override;
+	void varGetValue(DynamicValue &dest) const override;
 
 #ifdef MTROPOLIS_DEBUG_ENABLE
 	const char *debugGetTypeName() const override { return "String Variable Modifier"; }
@@ -1204,7 +1203,7 @@ public:
 	Common::SharedPtr<ModifierSaveLoad> getSaveLoad() override;
 
 	bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) override;
-	void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const override;
+	void varGetValue(DynamicValue &dest) const override;
 
 #ifdef MTROPOLIS_DEBUG_ENABLE
 	const char *debugGetTypeName() const override { return "Object Reference Variable Modifier V1"; }
diff --git a/engines/mtropolis/plugin/standard.cpp b/engines/mtropolis/plugin/standard.cpp
index 6cbf584ed83..bdf3867c32a 100644
--- a/engines/mtropolis/plugin/standard.cpp
+++ b/engines/mtropolis/plugin/standard.cpp
@@ -1879,7 +1879,7 @@ VThreadState MediaCueMessengerModifier::consumeMessage(Runtime *runtime, const C
 					}
 
 					DynamicValue value;
-					static_cast<VariableModifier *>(modifier)->varGetValue(nullptr, value);
+					static_cast<VariableModifier *>(modifier)->varGetValue(value);
 
 					switch (value.getType()) {
 					case DynamicValueTypes::kInteger:
@@ -2027,7 +2027,7 @@ bool ObjectReferenceVariableModifier::varSetValue(MiniscriptThread *thread, cons
 	}
 }
 
-void ObjectReferenceVariableModifier::varGetValue(MiniscriptThread *thread, DynamicValue &dest) const {
+void ObjectReferenceVariableModifier::varGetValue(DynamicValue &dest) const {
 	dest.setObject(this->getSelfReference());
 }
 
@@ -2759,7 +2759,7 @@ bool ListVariableModifier::load(const PlugInModifierLoaderContext &context, cons
 
 	for (size_t i = 0; i < data.numValues; i++) {
 		DynamicValue dynValue;
-		if (!dynValue.load(data.values[i]))
+		if (!dynValue.loadConstant(data.values[i]))
 			return false;
 
 		if (dynValue.getType() != expectedType) {
@@ -2794,7 +2794,7 @@ bool ListVariableModifier::varSetValue(MiniscriptThread *thread, const DynamicVa
 	return true;
 }
 
-void ListVariableModifier::varGetValue(MiniscriptThread *thread, DynamicValue &dest) const {
+void ListVariableModifier::varGetValue(DynamicValue &dest) const {
 	dest.setList(_list);
 }
 
@@ -2876,12 +2876,6 @@ void ListVariableModifier::debugInspect(IDebugInspectionReport *report) const {
 		case DynamicValueTypes::kEvent:
 			report->declareLoose(Common::String::format("[%i] = Event?", cardinal));
 			break;
-		case DynamicValueTypes::kVariableReference:
-			report->declareLoose(Common::String::format("[%i] = VarRef?", cardinal));
-			break;
-		case DynamicValueTypes::kIncomingData:
-			report->declareLoose(Common::String::format("[%i] = IncomingData??", cardinal));
-			break;
 		case DynamicValueTypes::kString:
 			report->declareLoose(Common::String::format("[%i] = ", cardinal) + _list->getString()[i]);
 			break;
diff --git a/engines/mtropolis/plugin/standard.h b/engines/mtropolis/plugin/standard.h
index 2cbe4e7bba3..b0c5cd38fd8 100644
--- a/engines/mtropolis/plugin/standard.h
+++ b/engines/mtropolis/plugin/standard.h
@@ -178,7 +178,7 @@ public:
 	MiniscriptInstructionOutcome writeRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &result, const Common::String &attrib) override;
 
 	bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) override;
-	void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const override;
+	void varGetValue(DynamicValue &dest) const override;
 
 #ifdef MTROPOLIS_DEBUG_ENABLE
 	const char *debugGetTypeName() const override { return "Object Reference Variable Modifier"; }
@@ -325,7 +325,7 @@ public:
 	Common::SharedPtr<ModifierSaveLoad> getSaveLoad() override;
 
 	bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) override;
-	void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const override;
+	void varGetValue(DynamicValue &dest) const override;
 
 	bool readAttribute(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib) override;
 	bool readAttributeIndexed(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib, const DynamicValue &index) override;
diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index 521cf7bece0..581ed2662e3 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -695,88 +695,6 @@ bool DynamicListContainer<void>::compareEqual(const DynamicListContainerBase &ot
 DynamicListContainerBase *DynamicListContainer<void>::clone() const {
 	return new DynamicListContainer<void>(*this);
 }
-
-bool DynamicListContainer<VarReference>::setAtIndex(size_t index, const DynamicValue &dynValue) {
-	if (dynValue.getType() != DynamicValueTypes::kVariableReference)
-		return false;
-
-	size_t requiredSize = index + 1;
-
-	if (_array.size() < requiredSize) {
-		size_t prevSize = _array.size();
-		_array.resize(requiredSize);
-
-		for (size_t i = prevSize; i < index; i++) {
-			_array[i].guid = 0;
-		}
-
-		const VarReference &varRef = dynValue.getVarReference();
-		_array[index].guid = varRef.guid;
-		_array[index].source = varRef.source;
-	} else {
-		const VarReference &varRef = dynValue.getVarReference();
-		_array[index].guid = varRef.guid;
-		_array[index].source = varRef.source;
-	}
-
-	return true;
-}
-
-void DynamicListContainer<VarReference>::truncateToSize(size_t sz) {
-	if (_array.size() > sz)
-		_array.resize(sz);
-}
-
-bool DynamicListContainer<VarReference>::expandToMinimumSize(size_t sz) {
-	if (_array.size() < sz) {
-		size_t prevSize = _array.size();
-		_array.resize(sz);
-
-		for (size_t i = prevSize; i < sz; i++) {
-			_array[i].guid = 0;
-			_array[i].source = "";
-		}
-	}
-
-	return true;
-}
-
-bool DynamicListContainer<VarReference>::getAtIndex(size_t index, DynamicValue &dynValue) const {
-	// TODO: Refactor this whole thing to use linkInternalReferences
-	if (index >= _array.size())
-		return false;
-
-	assert(false);
-	return false;
-}
-
-void DynamicListContainer<VarReference>::setFrom(const DynamicListContainerBase &other) {
-	const DynamicListContainer<VarReference> &otherTyped = static_cast<const DynamicListContainer<VarReference> &>(other);
-
-	_array = otherTyped._array;
-}
-
-const void *DynamicListContainer<VarReference>::getConstArrayPtr() const {
-	return &_array;
-}
-
-void *DynamicListContainer<VarReference>::getArrayPtr() {
-	return &_array;
-}
-
-size_t DynamicListContainer<VarReference>::getSize() const {
-	return _array.size();
-}
-
-bool DynamicListContainer<VarReference>::compareEqual(const DynamicListContainerBase &other) const {
-	const DynamicListContainer<VarReference> &otherTyped = static_cast<const DynamicListContainer<VarReference> &>(other);
-	return _array == otherTyped._array;
-}
-
-DynamicListContainerBase *DynamicListContainer<VarReference>::clone() const {
-	return new DynamicListContainer<VarReference>(*this);
-}
-
 DynamicList::DynamicList() : _type(DynamicValueTypes::kEmpty), _container(nullptr) {
 }
 
@@ -827,11 +745,6 @@ const Common::Array<Event> &DynamicList::getEvent() const {
 	return *static_cast<const Common::Array<Event> *>(_container->getConstArrayPtr());
 }
 
-const Common::Array<VarReference> &DynamicList::getVarReference() const {
-	assert(_type == DynamicValueTypes::kVariableReference);
-	return *static_cast<const Common::Array<VarReference> *>(_container->getConstArrayPtr());
-}
-
 const Common::Array<Common::String> &DynamicList::getString() const {
 	assert(_type == DynamicValueTypes::kString);
 	return *static_cast<const Common::Array<Common::String> *>(_container->getConstArrayPtr());
@@ -887,11 +800,6 @@ Common::Array<Event> &DynamicList::getEvent() {
 	return *static_cast<Common::Array<Event> *>(_container->getArrayPtr());
 }
 
-Common::Array<VarReference> &DynamicList::getVarReference() {
-	assert(_type == DynamicValueTypes::kVariableReference);
-	return *static_cast<Common::Array<VarReference> *>(_container->getArrayPtr());
-}
-
 Common::Array<Common::String> &DynamicList::getString() {
 	assert(_type == DynamicValueTypes::kString);
 	return *static_cast<Common::Array<Common::String> *>(_container->getArrayPtr());
@@ -1057,12 +965,6 @@ bool DynamicList::changeToType(DynamicValueTypes::DynamicValueType type) {
 	case DynamicValueTypes::kEvent:
 		_container = new DynamicListContainer<Event>();
 		break;
-	case DynamicValueTypes::kVariableReference:
-		_container = new DynamicListContainer<VarReference>();
-		break;
-	case DynamicValueTypes::kIncomingData:
-		_container = new DynamicListContainer<void>();
-		break;
 	case DynamicValueTypes::kString:
 		_container = new DynamicListContainer<Common::String>();
 		break;
@@ -1211,16 +1113,13 @@ DynamicValue::~DynamicValue() {
 	clear();
 }
 
-bool DynamicValue::load(const Data::InternalTypeTaggedValue &data, const Common::String &varSource, const Common::String &varString) {
+bool DynamicValue::loadConstant(const Data::InternalTypeTaggedValue &data, const Common::String &varString) {
 	clear();
 
 	switch (data.type) {
 	case Data::InternalTypeTaggedValue::kNull:
 		_type = DynamicValueTypes::kNull;
 		break;
-	case Data::InternalTypeTaggedValue::kIncomingData:
-		_type = DynamicValueTypes::kIncomingData;
-		break;
 	case Data::InternalTypeTaggedValue::kInteger:
 		_type = DynamicValueTypes::kInteger;
 		_value.construct<int32, &ValueUnion::asInt>(data.value.asInteger);
@@ -1247,10 +1146,6 @@ bool DynamicValue::load(const Data::InternalTypeTaggedValue &data, const Common:
 		_type = DynamicValueTypes::kBoolean;
 		_value.construct<bool, &ValueUnion::asBool>(data.value.asBool != 0);
 		break;
-	case Data::InternalTypeTaggedValue::kVariableReference:
-		_type = DynamicValueTypes::kVariableReference;
-		_value.construct<VarReference, &ValueUnion::asVarReference>(VarReference(data.value.asVariableReference.guid, varSource));
-		break;
 	case Data::InternalTypeTaggedValue::kLabel:
 		_type = DynamicValueTypes::kLabel;
 		_value.construct<Label, &ValueUnion::asLabel>(Label());
@@ -1265,16 +1160,13 @@ bool DynamicValue::load(const Data::InternalTypeTaggedValue &data, const Common:
 	return true;
 }
 
-bool DynamicValue::load(const Data::PlugInTypeTaggedValue &data) {
+bool DynamicValue::loadConstant(const Data::PlugInTypeTaggedValue &data) {
 	clear();
 
 	switch (data.type) {
 	case Data::PlugInTypeTaggedValue::kNull:
 		_type = DynamicValueTypes::kNull;
 		break;
-	case Data::PlugInTypeTaggedValue::kIncomingData:
-		_type = DynamicValueTypes::kIncomingData;
-		break;
 	case Data::PlugInTypeTaggedValue::kInteger:
 		_type = DynamicValueTypes::kInteger;
 		_value.construct<int32, &ValueUnion::asInt>(data.value.asInt);
@@ -1309,11 +1201,6 @@ bool DynamicValue::load(const Data::PlugInTypeTaggedValue &data) {
 		_type = DynamicValueTypes::kString;
 		_value.construct<Common::String, &ValueUnion::asString>(data.value.asString);
 		break;
-	case Data::PlugInTypeTaggedValue::kVariableReference:
-		_type = DynamicValueTypes::kVariableReference;
-		// Extra data doesn't seem to correlate with var source string in this case
-		_value.construct<VarReference, &ValueUnion::asVarReference>(VarReference(data.value.asVarRefGUID, ""));
-		break;
 	case Data::PlugInTypeTaggedValue::kPoint:
 		_type = DynamicValueTypes::kPoint;
 		_value.construct<Common::Point, &ValueUnion::asPoint>(Common::Point());
@@ -1367,11 +1254,6 @@ const Event &DynamicValue::getEvent() const {
 	return _value.asEvent;
 }
 
-const VarReference &DynamicValue::getVarReference() const {
-	assert(_type == DynamicValueTypes::kVariableReference);
-	return _value.asVarReference;
-}
-
 const Common::String &DynamicValue::getString() const {
 	assert(_type == DynamicValueTypes::kString);
 	return _value.asString;
@@ -1446,13 +1328,6 @@ void DynamicValue::setEvent(const Event &value) {
 	_value.construct<Event, &ValueUnion::asEvent>(value);
 }
 
-void DynamicValue::setVarReference(const VarReference &value) {
-	if (_type != DynamicValueTypes::kVariableReference)
-		clear();
-	_type = DynamicValueTypes::kVariableReference;
-	_value.construct<VarReference, &ValueUnion::asVarReference>(value);
-}
-
 void DynamicValue::setString(const Common::String &value) {
 	if (_type != DynamicValueTypes::kString)
 		clear();
@@ -1553,10 +1428,6 @@ bool DynamicValue::operator==(const DynamicValue &other) const {
 		return _value.asLabel == other._value.asLabel;
 	case DynamicValueTypes::kEvent:
 		return _value.asEvent == other._value.asEvent;
-	case DynamicValueTypes::kVariableReference:
-		return _value.asVarReference == other._value.asVarReference;
-	case DynamicValueTypes::kIncomingData:
-		return true;
 	case DynamicValueTypes::kString:
 		return _value.asString == other._value.asString;
 	case DynamicValueTypes::kBoolean:
@@ -1577,7 +1448,6 @@ void DynamicValue::clear() {
 	switch (_type) {
 	case DynamicValueTypes::kNull:
 	case DynamicValueTypes::kEmpty:
-	case DynamicValueTypes::kIncomingData:
 		_value.destruct<uint64, &ValueUnion::asUnset>();
 		break;
 	case DynamicValueTypes::kInteger:
@@ -1604,9 +1474,6 @@ void DynamicValue::clear() {
 	case DynamicValueTypes::kEvent:
 		_value.destruct<Event, &ValueUnion::asEvent>();
 		break;
-	case DynamicValueTypes::kVariableReference:
-		_value.destruct<VarReference, &ValueUnion::asVarReference>();
-		break;
 	case DynamicValueTypes::kString:
 		_value.destruct<Common::String, &ValueUnion::asString>();
 		break;
@@ -1695,7 +1562,6 @@ void DynamicValue::setFromOther(const DynamicValue &other) {
 
 	switch (other._type) {
 	case DynamicValueTypes::kNull:
-	case DynamicValueTypes::kIncomingData:
 	case DynamicValueTypes::kEmpty:
 		clear();
 		_type = other._type;
@@ -1721,9 +1587,6 @@ void DynamicValue::setFromOther(const DynamicValue &other) {
 	case DynamicValueTypes::kEvent:
 		setEvent(other._value.asEvent);
 		break;
-	case DynamicValueTypes::kVariableReference:
-		setVarReference(other._value.asVarReference);
-		break;
 	case DynamicValueTypes::kString:
 		setString(other._value.asString);
 		break;
@@ -1747,6 +1610,185 @@ void DynamicValue::setFromOther(const DynamicValue &other) {
 	assert(_type == other._type);
 }
 
+
+DynamicValueSource::DynamicValueSource() : _sourceType(DynamicValueSourceTypes::kInvalid) {
+}
+
+DynamicValueSource::DynamicValueSource(const DynamicValueSource &other) : _sourceType(DynamicValueSourceTypes::kInvalid) {
+	initFromOther(other);
+}
+
+DynamicValueSource::DynamicValueSource(DynamicValueSource &&other) : _sourceType(DynamicValueSourceTypes::kInvalid) {
+	initFromOther(static_cast<DynamicValueSource &&>(other));
+}
+
+DynamicValueSource::~DynamicValueSource() {
+	destructValue();
+}
+
+DynamicValueSource &DynamicValueSource::operator=(const DynamicValueSource &other) {
+	if (this == &other)
+		return *this;
+
+	destructValue();
+	initFromOther(other);
+	return *this;
+}
+
+DynamicValueSource &DynamicValueSource::operator=(DynamicValueSource &&other) {
+	if (this == &other)
+		return *this;
+
+	destructValue();
+	initFromOther(static_cast<DynamicValueSource &&>(other));
+	return *this;
+}
+
+DynamicValueSourceTypes::DynamicValueSourceType DynamicValueSource::getSourceType() const {
+	return _sourceType;
+}
+
+const DynamicValue &DynamicValueSource::getConstant() const {
+	assert(_sourceType == DynamicValueSourceTypes::kConstant);
+	return _valueUnion._constValue;
+}
+const VarReference &DynamicValueSource::getVarReference() const {
+	assert(_sourceType == DynamicValueSourceTypes::kVariableReference);
+	return _valueUnion._varReference;
+}
+
+bool DynamicValueSource::load(const Data::InternalTypeTaggedValue &data, const Common::String &varSource, const Common::String &varString) {
+	destructValue();
+
+	switch (data.type)
+	{
+	case Data::InternalTypeTaggedValue::kIncomingData:
+		_sourceType = DynamicValueSourceTypes::kIncomingData;
+		return true;
+	case Data::InternalTypeTaggedValue::kVariableReference:
+		_sourceType = DynamicValueSourceTypes::kVariableReference;
+		new (&_valueUnion._varReference) VarReference(data.value.asVariableReference.guid, varSource);
+		return true;
+	default:
+		_sourceType = DynamicValueSourceTypes::kConstant;
+		new (&_valueUnion._constValue) DynamicValue();
+		return _valueUnion._constValue.loadConstant(data, varString);
+	}
+
+	assert(false);
+	return false;
+}
+
+bool DynamicValueSource::load(const Data::PlugInTypeTaggedValue &data) {
+	destructValue();
+
+	switch (data.type) {
+	case Data::PlugInTypeTaggedValue::kIncomingData:
+		_sourceType = DynamicValueSourceTypes::kIncomingData;
+		return true;
+	case Data::PlugInTypeTaggedValue::kVariableReference:
+		_sourceType = DynamicValueSourceTypes::kVariableReference;
+		new (&_valueUnion._varReference) VarReference(data.value.asVarRefGUID, "");
+		return true;
+	default:
+		_sourceType = DynamicValueSourceTypes::kConstant;
+		new (&_valueUnion._constValue) DynamicValue();
+		return _valueUnion._constValue.loadConstant(data);
+	}
+}
+
+
+void DynamicValueSource::linkInternalReferences(ObjectLinkingScope *scope) {
+	if (_sourceType == DynamicValueSourceTypes::kVariableReference) {
+		_valueUnion._varReference.linkInternalReferences(scope);
+	}
+}
+
+void DynamicValueSource::visitInternalReferences(IStructuralReferenceVisitor *visitor) {
+	if (_sourceType == DynamicValueSourceTypes::kVariableReference) {
+		_valueUnion._varReference.visitInternalReferences(visitor);
+	}
+}
+
+DynamicValue DynamicValueSource::produceValue(const DynamicValue &incomingData) const {
+	switch (_sourceType) {
+	case DynamicValueSourceTypes::kConstant:
+		return _valueUnion._constValue;
+	case DynamicValueSourceTypes::kIncomingData:
+		return incomingData;
+	case DynamicValueSourceTypes::kVariableReference: {
+			Common::SharedPtr<Modifier> resolution = _valueUnion._varReference.resolution.lock();
+			if (resolution->isVariable()) {
+				DynamicValue result;
+				static_cast<VariableModifier *>(resolution.get())->varGetValue(result);
+				return result;
+			} else {
+				warning("Dynamic value source wasn't a variable");
+				return DynamicValue();
+			}
+		} break;
+	default:
+		warning("Dynamic value couldn't be resolved");
+		return DynamicValue();
+	}
+}
+
+
+DynamicValueSource::ValueUnion::ValueUnion() {
+}
+
+DynamicValueSource::ValueUnion::~ValueUnion() {
+}
+
+void DynamicValueSource::destructValue() {
+	switch (_sourceType) {
+	case DynamicValueSourceTypes::kConstant:
+		_valueUnion._constValue.~DynamicValue();
+		break;
+	case DynamicValueSourceTypes::kVariableReference:
+		_valueUnion._varReference.~VarReference();
+		break;
+	default:
+		break;
+	}
+
+	_sourceType = DynamicValueSourceTypes::kInvalid;
+}
+
+void DynamicValueSource::initFromOther(const DynamicValueSource &other) {
+	assert(_sourceType == DynamicValueSourceTypes::kInvalid);
+
+	switch (other._sourceType) {
+	case DynamicValueSourceTypes::kConstant:
+		new (&_valueUnion._constValue) DynamicValue(other._valueUnion._constValue);
+		break;
+	case DynamicValueSourceTypes::kVariableReference:
+		new (&_valueUnion._varReference) VarReference(other._valueUnion._varReference);
+		break;
+	default:
+		break;
+	}
+
+	_sourceType = other._sourceType;
+}
+
+void DynamicValueSource::initFromOther(DynamicValueSource &&other) {
+	assert(_sourceType == DynamicValueSourceTypes::kInvalid);
+
+	switch (other._sourceType) {
+	case DynamicValueSourceTypes::kConstant:
+		new (&_valueUnion._constValue) DynamicValue(static_cast<DynamicValue &&>(other._valueUnion._constValue));
+		break;
+	case DynamicValueSourceTypes::kVariableReference:
+		new (&_valueUnion._varReference) VarReference(static_cast<VarReference &&>(other._valueUnion._varReference));
+		break;
+	default:
+		break;
+	}
+
+	_sourceType = other._sourceType;
+}
+
 MiniscriptInstructionOutcome DynamicValueWriteStringHelper::write(MiniscriptThread *thread, const DynamicValue &value, void *objectRef, uintptr ptrOrOffset) {
 	Common::String &dest = *static_cast<Common::String *>(objectRef);
 	switch (value.getType()) {
@@ -1954,19 +1996,7 @@ void MessengerSendSpec::linkInternalReferences(ObjectLinkingScope *outerScope) {
 		} break;
 	}
 
-	if (this->with.getType() == DynamicValueTypes::kVariableReference) {
-		const VarReference &varRef = this->with.getVarReference();
-
-		Common::WeakPtr<RuntimeObject> resolution = outerScope->resolve(varRef.guid, varRef.source, false);
-		if (!resolution.expired()) {
-			Common::SharedPtr<RuntimeObject> obj = resolution.lock();
-			if (obj->isModifier())
-				_resolvedVarSource = obj.staticCast<Modifier>();
-			else {
-				warning("Messenger variable source wasn't a variable");
-			}
-		}
-	}
+	with.linkInternalReferences(outerScope);
 }
 
 void MessengerSendSpec::visitInternalReferences(IStructuralReferenceVisitor *visitor) {
@@ -2097,18 +2127,7 @@ void MessengerSendSpec::resolveVariableObjectType(RuntimeObject *obj, Common::We
 }
 
 void MessengerSendSpec::sendFromMessenger(Runtime *runtime, Modifier *sender, const DynamicValue &incomingData, RuntimeObject *customDestination) const {
-	const DynamicValueTypes::DynamicValueType withType = with.getType();
-	if (withType == DynamicValueTypes::kIncomingData)
-		sendFromMessengerWithCustomData(runtime, sender, incomingData, customDestination);
-	else if (withType == DynamicValueTypes::kVariableReference) {
-		DynamicValue payload;
-		Modifier *modifier = _resolvedVarSource.lock().get();
-		if (modifier && modifier->isVariable())
-			static_cast<VariableModifier *>(modifier)->varGetValue(nullptr, payload);
-
-		sendFromMessengerWithCustomData(runtime, sender, payload, customDestination);
-	} else
-		sendFromMessengerWithCustomData(runtime, sender, this->with, customDestination);
+	sendFromMessengerWithCustomData(runtime, sender, this->with.produceValue(incomingData), customDestination);
 }
 
 void MessengerSendSpec::sendFromMessengerWithCustomData(Runtime *runtime, Modifier *sender, const DynamicValue &data, RuntimeObject *customDestination) const {
@@ -2227,6 +2246,26 @@ bool VarReference::resolve(Modifier *modifierScope, Common::WeakPtr<RuntimeObjec
 	return false;
 }
 
+void VarReference::linkInternalReferences(ObjectLinkingScope *scope) {
+	if (guid) {
+		Common::WeakPtr<RuntimeObject> obj = scope->resolve(guid, source, false);
+		if (obj.expired()) {
+			warning("VarReference to '%s' failed to resolve a valid object", source.c_str());
+		} else {
+			Common::SharedPtr<RuntimeObject> objShr = obj.lock();
+			if (objShr->isModifier() && static_cast<Modifier *>(objShr.get())->isVariable()) {
+				this->resolution = obj.staticCast<Modifier>();
+			} else {
+				error("VarReference referenced a non-variable");
+			}
+		}
+	}
+}
+
+void VarReference::visitInternalReferences(IStructuralReferenceVisitor *visitor) {
+	visitor->visitWeakModifierRef(this->resolution);
+}
+
 bool VarReference::resolveContainer(IModifierContainer *modifierContainer, Common::WeakPtr<RuntimeObject> &outObject) const {
 	for (const Common::SharedPtr<Modifier> &modifier : modifierContainer->getModifiers())
 		if (resolveSingleModifier(modifier.get(), outObject))
@@ -8440,7 +8479,7 @@ bool VariableModifier::isVariable() const {
 
 bool VariableModifier::readAttribute(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib) {
 	if (attrib == "value") {
-		varGetValue(thread, result);
+		varGetValue(result);
 		return true;
 	}
 
diff --git a/engines/mtropolis/runtime.h b/engines/mtropolis/runtime.h
index 73f6e22ae06..351ebb6d5eb 100644
--- a/engines/mtropolis/runtime.h
+++ b/engines/mtropolis/runtime.h
@@ -179,28 +179,38 @@ enum MouseInteractivityTestType {
 	kMouseInteractivityTestMouseClick,
 };
 
+namespace DynamicValueSourceTypes {
+	enum DynamicValueSourceType {
+		kInvalid,
+
+		kConstant,
+		kVariableReference,
+		kIncomingData,
+	};
+}
+
 namespace DynamicValueTypes {
 
+// These values are stored in the saved game format, so they must be stable
 enum DynamicValueType {
-	kInvalid,
-
-	kNull,
-	kInteger,
-	kFloat,
-	kPoint,
-	kIntegerRange,
-	kBoolean,
-	kVector,
-	kLabel,
-	kEvent,
-	kVariableReference,
-	kIncomingData,
-	kString,
-	kList,
-	kObject,
-	kWriteProxy,
-
-	kEmpty,
+	kInvalid = 0,
+
+	kNull = 1,
+	kInteger = 2,
+	kFloat = 3,
+	kPoint = 4,
+	kIntegerRange = 5,
+	kBoolean = 6,
+	kVector = 7,
+	kLabel = 8,
+	kEvent = 9,
+
+	kString = 12,
+	kList = 13,
+	kObject = 14,
+	kWriteProxy = 15,
+
+	kEmpty = 16,
 };
 
 } // End of namespace DynamicValuesTypes
@@ -387,6 +397,7 @@ struct VarReference {
 
 	uint32 guid;
 	Common::String source;
+	Common::WeakPtr<Modifier> resolution;
 
 	inline bool operator==(const VarReference &other) const {
 		return guid == other.guid && source == other.source;
@@ -399,6 +410,9 @@ struct VarReference {
 	bool resolve(Structural *structuralScope, Common::WeakPtr<RuntimeObject> &outObject) const;
 	bool resolve(Modifier *modifierScope, Common::WeakPtr<RuntimeObject> &outObject) const;
 
+	void linkInternalReferences(ObjectLinkingScope *scope);
+	void visitInternalReferences(IStructuralReferenceVisitor *visitor);
+
 private:
 	bool resolveContainer(IModifierContainer *modifierContainer, Common::WeakPtr<RuntimeObject> &outObject) const;
 	bool resolveSingleModifier(Modifier *modifier, Common::WeakPtr<RuntimeObject> &outObject) const;
@@ -647,26 +661,6 @@ public:
 	size_t _size;
 };
 
-template<>
-class DynamicListContainer<VarReference> : public DynamicListContainerBase {
-public:
-	bool setAtIndex(size_t index, const DynamicValue &dynValue) override;
-	bool getAtIndex(size_t index, DynamicValue &dynValue) const override;
-	void truncateToSize(size_t sz) override;
-	bool expandToMinimumSize(size_t sz) override;
-	void setFrom(const DynamicListContainerBase &other) override;
-	const void *getConstArrayPtr() const override;
-	void *getArrayPtr() override;
-	size_t getSize() const override;
-	bool compareEqual(const DynamicListContainerBase &other) const override;
-	DynamicListContainerBase *clone() const override;
-
-private:
-	void rebuildStringPointers();
-
-	Common::Array<VarReference> _array;
-};
-
 template<class T>
 bool DynamicListContainer<T>::setAtIndex(size_t index, const DynamicValue &dynValue) {
 	const typename DynamicListValueConverter<T>::DynamicValuePODType_t *valuePtr = nullptr;
@@ -764,7 +758,6 @@ struct DynamicList {
 	const Common::Array<AngleMagVector> &getVector() const;
 	const Common::Array<Label> &getLabel() const;
 	const Common::Array<Event> &getEvent() const;
-	const Common::Array<VarReference> &getVarReference() const;
 	const Common::Array<Common::String> &getString() const;
 	const Common::Array<bool> &getBool() const;
 	const Common::Array<Common::SharedPtr<DynamicList> > &getList() const;
@@ -777,7 +770,6 @@ struct DynamicList {
 	Common::Array<AngleMagVector> &getVector();
 	Common::Array<Label> &getLabel();
 	Common::Array<Event> &getEvent();
-	Common::Array<VarReference> &getVarReference();
 	Common::Array<Common::String> &getString();
 	Common::Array<bool> &getBool();
 	Common::Array<Common::SharedPtr<DynamicList> > &getList();
@@ -826,8 +818,8 @@ struct DynamicValue {
 	DynamicValue(const DynamicValue &other);
 	~DynamicValue();
 
-	bool load(const Data::InternalTypeTaggedValue &data, const Common::String &varSource, const Common::String &varString);
-	bool load(const Data::PlugInTypeTaggedValue &data);
+	bool loadConstant(const Data::InternalTypeTaggedValue &data, const Common::String &varString);
+	bool loadConstant(const Data::PlugInTypeTaggedValue &data);
 
 	DynamicValueTypes::DynamicValueType getType() const;
 
@@ -838,7 +830,6 @@ struct DynamicValue {
 	const AngleMagVector &getVector() const;
 	const Label &getLabel() const;
 	const Event &getEvent() const;
-	const VarReference &getVarReference() const;
 	const Common::String &getString() const;
 	const bool &getBool() const;
 	const Common::SharedPtr<DynamicList> &getList() const;
@@ -854,7 +845,6 @@ struct DynamicValue {
 	void setVector(const AngleMagVector &value);
 	void setLabel(const Label &value);
 	void setEvent(const Event &value);
-	void setVarReference(const VarReference &value);
 	void setString(const Common::String &value);
 	void setBool(bool value);
 	void setList(const Common::SharedPtr<DynamicList> &value);
@@ -883,7 +873,6 @@ private:
 		IntRange asIntRange;
 		AngleMagVector asVector;
 		Label asLabel;
-		VarReference asVarReference;
 		Event asEvent;
 		Common::Point asPoint;
 		bool asBool;
@@ -921,6 +910,44 @@ private:
 	ValueUnion _value;
 };
 
+struct DynamicValueSource {
+	DynamicValueSource();
+	DynamicValueSource(const DynamicValueSource &other);
+	DynamicValueSource(DynamicValueSource &&other);
+	~DynamicValueSource();
+
+	DynamicValueSource &operator=(const DynamicValueSource &other);
+	DynamicValueSource &operator=(DynamicValueSource &&other);
+
+	DynamicValueSourceTypes::DynamicValueSourceType getSourceType() const;
+	const DynamicValue &getConstant() const;
+	const VarReference &getVarReference() const;
+
+	bool load(const Data::InternalTypeTaggedValue &data, const Common::String &varSource, const Common::String &varString);
+	bool load(const Data::PlugInTypeTaggedValue &data);
+
+	void linkInternalReferences(ObjectLinkingScope *scope);
+	void visitInternalReferences(IStructuralReferenceVisitor *visitor);
+
+	DynamicValue produceValue(const DynamicValue &incomingData) const;
+
+private:
+	union ValueUnion {
+		ValueUnion();
+		~ValueUnion();
+
+		DynamicValue _constValue;
+		VarReference _varReference;
+	};
+
+	void destructValue();
+	void initFromOther(const DynamicValueSource &other);
+	void initFromOther(DynamicValueSource &&other);
+
+	DynamicValueSourceTypes::DynamicValueSourceType _sourceType;
+	ValueUnion _valueUnion;
+};
+
 template<class TFloat>
 struct DynamicValueWriteFloatHelper {
 	static MiniscriptInstructionOutcome write(MiniscriptThread *thread, const DynamicValue &value, void *objectRef, uintptr ptrOrOffset) {
@@ -1082,7 +1109,7 @@ struct MessengerSendSpec {
 
 	Event send;
 	MessageFlags messageFlags;
-	DynamicValue with;
+	DynamicValueSource with;
 	uint32 destination; // May be a MessageDestination or GUID
 
 	LinkType _linkType;
@@ -2828,7 +2855,7 @@ class VariableModifier : public Modifier {
 public:
 	virtual bool isVariable() const override;
 	virtual bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) = 0;
-	virtual void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const = 0;
+	virtual void varGetValue(DynamicValue &dest) const = 0;
 	virtual Common::SharedPtr<ModifierSaveLoad> getSaveLoad() override = 0;
 
 	bool readAttribute(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib) override;




More information about the Scummvm-git-logs mailing list