MTROPOLIS: Add support for "object" attrib of ObjectReferenceVariableModifierV1, and for sending play ranges to mToons. Fixes the pie minigame in MTI.

This commit is contained in:
elasota 2023-06-07 01:53:52 -04:00
parent 81ce20b4df
commit bd33eb0f80
5 changed files with 57 additions and 23 deletions

View File

@ -1213,6 +1213,9 @@ MiniscriptInstructionOutcome MToonElement::writeRefAttribute(MiniscriptThread *t
VThreadState MToonElement::consumeCommand(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
if (Event(EventIDs::kPlay, 0).respondsTo(msg->getEvent())) {
// If the range set fails, then the mToon should play anyway, so ignore the result
(void)scriptSetRange(nullptr, msg->getValue());
StartPlayingTaskData *startPlayingTaskData = runtime->getVThread().pushTask("MToonElement::startPlayingTask", this, &MToonElement::startPlayingTask);
startPlayingTaskData->runtime = runtime;
@ -1227,7 +1230,7 @@ VThreadState MToonElement::consumeCommand(Runtime *runtime, const Common::Shared
becomeVisibleTaskData->desiredFlag = false;
becomeVisibleTaskData->runtime = runtime;
StopPlayingTaskData *stopPlayingTaskData = runtime->getVThread().pushTask("MToonElement::startPlayingTask", this, &MToonElement::stopPlayingTask);
StopPlayingTaskData *stopPlayingTaskData = runtime->getVThread().pushTask("MToonElement::stopPlayingTask", this, &MToonElement::stopPlayingTask);
stopPlayingTaskData->runtime = runtime;
return kVThreadReturn;
}
@ -1553,30 +1556,12 @@ MiniscriptInstructionOutcome MToonElement::scriptSetRange(MiniscriptThread *thre
return scriptSetRangeTyped(thread, value.getIntRange());
if (value.getType() == DynamicValueTypes::kPoint)
return scriptSetRangeTyped(thread, value.getPoint());
if (value.getType() == DynamicValueTypes::kLabel) {
const Common::String *nameStrPtr = thread->getRuntime()->getProject()->findNameOfLabel(value.getLabel());
if (!nameStrPtr) {
thread->error("mToon range label wasn't found");
return kMiniscriptInstructionOutcomeFailed;
}
if (value.getType() == DynamicValueTypes::kLabel)
return scriptSetRangeTyped(thread, value.getLabel());
if (!_metadata) {
thread->error("mToon range couldn't be resolved because the metadata wasn't loaded yet");
return kMiniscriptInstructionOutcomeFailed;
}
if (thread)
thread->error("Invalid type for mToon range");
for (const MToonMetadata::FrameRangeDef &frameRange : _metadata->frameRanges) {
if (caseInsensitiveEqual(frameRange.name, *nameStrPtr)) {
// Frame ranges in the metadata are 0-based, but setting the range is 1-based, so add 1
return scriptSetRangeTyped(thread, IntRange(frameRange.startFrame + 1, frameRange.endFrame + 1));
}
}
thread->error("mToon range was assigned to a label but the label doesn't exist in the mToon data");
return kMiniscriptInstructionOutcomeFailed;
}
thread->error("Invalid type for mToon range");
return kMiniscriptInstructionOutcomeFailed;
}
@ -1660,6 +1645,33 @@ MiniscriptInstructionOutcome MToonElement::scriptSetRangeTyped(MiniscriptThread
return scriptSetRangeTyped(thread, intRange);
}
MiniscriptInstructionOutcome MToonElement::scriptSetRangeTyped(MiniscriptThread *thread, const Label &label) {
const Common::String *nameStrPtr = getRuntime()->getProject()->findNameOfLabel(label);
if (!nameStrPtr) {
if (thread)
thread->error("mToon range label wasn't found");
return kMiniscriptInstructionOutcomeFailed;
}
if (!_metadata) {
if (thread)
thread->error("mToon range couldn't be resolved because the metadata wasn't loaded yet");
return kMiniscriptInstructionOutcomeFailed;
}
for (const MToonMetadata::FrameRangeDef &frameRange : _metadata->frameRanges) {
if (caseInsensitiveEqual(frameRange.name, *nameStrPtr)) {
// Frame ranges in the metadata are 0-based, but setting the range is 1-based, so add 1
return scriptSetRangeTyped(thread, IntRange(frameRange.startFrame + 1, frameRange.endFrame + 1));
}
}
if (thread)
thread->error("mToon range was assigned to a label but the label doesn't exist in the mToon data");
return kMiniscriptInstructionOutcomeFailed;
}
void MToonElement::onPauseStateChanged() {
_celStartTimeMSec = getRuntime()->getPlayTime();
}

View File

@ -269,6 +269,7 @@ private:
MiniscriptInstructionOutcome scriptRangeWriteRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &result, const Common::String &attrib);
MiniscriptInstructionOutcome scriptSetRangeTyped(MiniscriptThread *thread, const IntRange &value);
MiniscriptInstructionOutcome scriptSetRangeTyped(MiniscriptThread *thread, const Common::Point &value);
MiniscriptInstructionOutcome scriptSetRangeTyped(MiniscriptThread *thread, const Label &value);
void onPauseStateChanged() override;

View File

@ -3504,6 +3504,21 @@ VThreadState ObjectReferenceVariableModifierV1::consumeMessage(Runtime *runtime,
return kVThreadError;
}
bool ObjectReferenceVariableModifierV1::readAttribute(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib) {
if (attrib == "object") {
ObjectReferenceVariableV1Storage *storage = static_cast<ObjectReferenceVariableV1Storage *>(_storage.get());
if (storage->_value.expired())
result.clear();
else
result.setObject(storage->_value);
return true;
}
return VariableModifier::readAttribute(thread, result, attrib);
}
bool ObjectReferenceVariableModifierV1::varSetValue(MiniscriptThread *thread, const DynamicValue &value) {
ObjectReferenceVariableV1Storage *storage = static_cast<ObjectReferenceVariableV1Storage *>(_storage.get());

View File

@ -1482,6 +1482,7 @@ public:
bool respondsToEvent(const Event &evt) const override;
VThreadState consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) override;
bool readAttribute(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib) override;
#ifdef MTROPOLIS_DEBUG_ENABLE
const char *debugGetTypeName() const override { return "Object Reference Variable Modifier V1"; }

View File

@ -5512,6 +5512,11 @@ void Runtime::sendMessageOnVThread(const Common::SharedPtr<MessageDispatch> &dis
if (RuntimeObject *obj = payload.getObject().object.lock().get())
valueStr += Common::String::format(" %x", obj->getStaticGUID());
break;
case DynamicValueTypes::kLabel:
valueStr = Common::String::format("Label(%u,%u)", static_cast<uint>(payload.getLabel().superGroupID), static_cast<uint>(payload.getLabel().id));
if (const Common::String *labelName = _project->findNameOfLabel(payload.getLabel()))
valueStr = valueStr + "[\"" + (*labelName) + "\"]";
break;
default:
valueStr = "<BAD TYPE> (this is a bug!)";
break;