mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 14:51:40 +00:00
MADS: Implement conversation conditionals evaluation
This commit is contained in:
parent
9e672dab60
commit
a0eacd0537
@ -151,6 +151,9 @@ void GameConversations::start() {
|
|||||||
_runningConv->_cnd._currentNode = -1;
|
_runningConv->_cnd._currentNode = -1;
|
||||||
_runningConv->_cnd._numImports = 0;
|
_runningConv->_cnd._numImports = 0;
|
||||||
_runningConv->_cnd._vars[0].setValue(_nextStartNode->_val);
|
_runningConv->_cnd._vars[0].setValue(_nextStartNode->_val);
|
||||||
|
|
||||||
|
// Store a reference to the variables list in the script handler for later reference
|
||||||
|
ScriptEntry::Conditional::_vars = &_runningConv->_cnd._vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameConversations::setVariable(uint idx, int val) {
|
void GameConversations::setVariable(uint idx, int val) {
|
||||||
@ -441,7 +444,16 @@ int GameConversations::executeEntry(int index) {
|
|||||||
bool flag = true;
|
bool flag = true;
|
||||||
for (uint scriptIdx = 0; scriptIdx < dlg._script.size(); ++scriptIdx) {
|
for (uint scriptIdx = 0; scriptIdx < dlg._script.size(); ++scriptIdx) {
|
||||||
DialogCommand cmd = dlg._script[scriptIdx]._command;
|
DialogCommand cmd = dlg._script[scriptIdx]._command;
|
||||||
// TODO
|
|
||||||
|
switch (cmd) {
|
||||||
|
case CMD_1:
|
||||||
|
case CMD_HIDE:
|
||||||
|
case CMD_UNHIDE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error("Unknown script opcode");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
@ -774,10 +786,14 @@ void ScriptEntry::load(Common::SeekableReadStream &s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEntry::Conditional::load(Common::SeekableReadStream &s) {
|
/*------------------------------------------------------------------------*/
|
||||||
_paramsFlag = s.readUint16LE();
|
|
||||||
|
|
||||||
if (_paramsFlag == 0xff) {
|
Common::Array<ConversationVar> *ScriptEntry::Conditional::_vars = nullptr;
|
||||||
|
|
||||||
|
void ScriptEntry::Conditional::load(Common::SeekableReadStream &s) {
|
||||||
|
_operation = (ConditionalOperation)s.readUint16LE();
|
||||||
|
|
||||||
|
if (_operation == CNVOP_ABORT) {
|
||||||
_param1._isVariable = false;
|
_param1._isVariable = false;
|
||||||
_param1._val = 0;
|
_param1._val = 0;
|
||||||
_param2._isVariable = false;
|
_param2._isVariable = false;
|
||||||
@ -790,62 +806,53 @@ void ScriptEntry::Conditional::load(Common::SeekableReadStream &s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int ScriptEntry::Conditional::evaluate() const {
|
||||||
do {
|
if (_operation == CNVOP_NONE)
|
||||||
command = convFile->readByte();
|
return -1;
|
||||||
chk = convFile->readUint16BE();
|
|
||||||
if (chk != 0xFF00 && chk != 0x0000) {
|
int param1 = get(0);
|
||||||
warning("Error while reading conversation node entries - bailing out");
|
if (_operation == CNVOP_VALUE)
|
||||||
break;
|
return param1;
|
||||||
|
int param2 = get(1);
|
||||||
|
|
||||||
|
switch (_operation) {
|
||||||
|
case CNVOP_ADD:
|
||||||
|
return param1 + param2;
|
||||||
|
case CNVOP_SUBTRACT:
|
||||||
|
return param1 - param2;
|
||||||
|
case CNVOP_MULTIPLY:
|
||||||
|
return param1 * param2;
|
||||||
|
case CNVOP_DIVIDE:
|
||||||
|
return param1 / param2;
|
||||||
|
case CNVOP_MODULUS:
|
||||||
|
return param1 % param2;
|
||||||
|
case CNVOP_LTEQ:
|
||||||
|
return (param1 <= param2) ? 1 : 0;
|
||||||
|
case CNVOP_GTEQ:
|
||||||
|
return (param1 < param2) ? 1 : 0;
|
||||||
|
case CNVOP_LT:
|
||||||
|
return (param1 < param2) ? 1 : 0;
|
||||||
|
case CNVOP_GT:
|
||||||
|
return (param1 > param2) ? 1 : 0;
|
||||||
|
case CNVOP_NEQ:
|
||||||
|
return (param1 != param2) ? 1 : 0;
|
||||||
|
case CNVOP_EQ:
|
||||||
|
return (param1 == param2) ? 1 : 0;
|
||||||
|
case CNVOP_AND:
|
||||||
|
return (param1 || param2) ? 1 : 0;
|
||||||
|
case CNVOP_OR:
|
||||||
|
return (param1 && param2) ? 1 : 0;
|
||||||
|
default:
|
||||||
|
error("Unknown conditional operation");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (command) {
|
int ScriptEntry::Conditional::get(int paramNum) const {
|
||||||
case cmdNodeEnd:
|
const CondtionalParamEntry &p = (paramNum == 0) ? _param1 : _param2;
|
||||||
//debug("Node end");
|
return p._isVariable ? *(*_vars)[p._val].getValue() : p._val;
|
||||||
break;
|
|
||||||
case cmdDialogEnd:
|
|
||||||
//debug("Dialog end");
|
|
||||||
break;
|
|
||||||
case cmdHide: {
|
|
||||||
byte count = convFile->readByte();
|
|
||||||
for (byte k = 0; k < count; k++) {
|
|
||||||
//uint16 nodeRef = convFile->readUint16LE();
|
|
||||||
//debug("Hide node %d", nodeRef);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
/*------------------------------------------------------------------------*/
|
||||||
break;
|
|
||||||
case cmdUnhide: {
|
|
||||||
byte count = convFile->readByte();
|
|
||||||
for (byte k = 0; k < count; k++) {
|
|
||||||
//uint16 nodeRef = convFile->readUint16LE();
|
|
||||||
//debug("Unhide node %d", nodeRef);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case cmdMessage:
|
|
||||||
//debug("Message");
|
|
||||||
convFile->skip(7); // TODO
|
|
||||||
break;
|
|
||||||
case cmdGoto: {
|
|
||||||
convFile->skip(3); // unused?
|
|
||||||
//byte nodeRef = convFile->readByte();
|
|
||||||
//debug("Goto %d", nodeRef);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case cmdAssign: {
|
|
||||||
convFile->skip(3); // unused?
|
|
||||||
//uint16 value = convFile->readUint16LE();
|
|
||||||
//uint16 variable = convFile->readUint16LE();
|
|
||||||
//debug("Variable %d = %d", variable, value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error("Unknown conversation command %d", command);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (command != cmdNodeEnd && command != cmdDialogEnd);
|
|
||||||
*/
|
|
||||||
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
@ -68,6 +68,62 @@ enum ConvEntryFlag {
|
|||||||
ENTRYFLAG_8000 = 0x8000
|
ENTRYFLAG_8000 = 0x8000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ConditionalOperation {
|
||||||
|
CNVOP_NONE = 0xff,
|
||||||
|
CNVOP_VALUE = 0,
|
||||||
|
CNVOP_ADD = 1,
|
||||||
|
CNVOP_SUBTRACT = 2,
|
||||||
|
CNVOP_MULTIPLY = 3,
|
||||||
|
CNVOP_DIVIDE = 4,
|
||||||
|
CNVOP_MODULUS = 5,
|
||||||
|
CNVOP_LTEQ = 6,
|
||||||
|
CNVOP_GTEQ = 7,
|
||||||
|
CNVOP_LT = 8,
|
||||||
|
CNVOP_GT = 9,
|
||||||
|
CNVOP_NEQ = 10,
|
||||||
|
CNVOP_EQ = 11,
|
||||||
|
CNVOP_AND = 12,
|
||||||
|
CNVOP_OR = 13,
|
||||||
|
CNVOP_ABORT = 0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ConversationVar {
|
||||||
|
bool _isPtr;
|
||||||
|
int _val;
|
||||||
|
int *_valPtr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
ConversationVar() : _isPtr(false), _val(0), _valPtr(nullptr) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a numeric value
|
||||||
|
*/
|
||||||
|
void setValue(int val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a pointer value
|
||||||
|
*/
|
||||||
|
void setValue(int *val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return either the variable's pointer, or a pointer to it's direct value
|
||||||
|
*/
|
||||||
|
int *getValue() { return _isPtr ? _valPtr : &_val; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if variable is a pointer
|
||||||
|
*/
|
||||||
|
bool isPtr() const { return _isPtr; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if variable is numeric
|
||||||
|
*/
|
||||||
|
bool isNumeric() const { return !_isPtr; }
|
||||||
|
};
|
||||||
|
|
||||||
struct ScriptEntry {
|
struct ScriptEntry {
|
||||||
struct Conditional {
|
struct Conditional {
|
||||||
struct CondtionalParamEntry {
|
struct CondtionalParamEntry {
|
||||||
@ -80,19 +136,30 @@ struct ScriptEntry {
|
|||||||
CondtionalParamEntry() : _isVariable(false), _val(0) {}
|
CondtionalParamEntry() : _isVariable(false), _val(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
uint _paramsFlag;
|
static Common::Array<ConversationVar> *_vars;
|
||||||
|
ConditionalOperation _operation;
|
||||||
CondtionalParamEntry _param1;
|
CondtionalParamEntry _param1;
|
||||||
CondtionalParamEntry _param2;
|
CondtionalParamEntry _param2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
Conditional() : _paramsFlag(false) {}
|
Conditional() : _operation(CNVOP_NONE) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads data from a passed stream into the parameters structure
|
* Loads data from a passed stream into the parameters structure
|
||||||
*/
|
*/
|
||||||
void load(Common::SeekableReadStream &s);
|
void load(Common::SeekableReadStream &s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value
|
||||||
|
*/
|
||||||
|
int get(int paramNum) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates the conditional
|
||||||
|
*/
|
||||||
|
int evaluate() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
DialogCommand _command;
|
DialogCommand _command;
|
||||||
@ -178,42 +245,6 @@ struct ConversationData {
|
|||||||
void load(const Common::String &filename);
|
void load(const Common::String &filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConversationVar {
|
|
||||||
bool _isPtr;
|
|
||||||
int _val;
|
|
||||||
int *_valPtr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
ConversationVar() : _isPtr(false), _val(0), _valPtr(nullptr) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a numeric value
|
|
||||||
*/
|
|
||||||
void setValue(int val);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a pointer value
|
|
||||||
*/
|
|
||||||
void setValue(int *val);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return either the variable's pointer, or a pointer to it's direct value
|
|
||||||
*/
|
|
||||||
int *getValue() { return _isPtr ? _valPtr : &_val; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if variable is a pointer
|
|
||||||
*/
|
|
||||||
bool isPtr() const { return _isPtr; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if variable is numeric
|
|
||||||
*/
|
|
||||||
bool isNumeric() const { return !_isPtr; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conditional (i.e. changeable) data for the conversation
|
* Conditional (i.e. changeable) data for the conversation
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user