Files
2026-02-02 04:50:13 +01:00

205 lines
4.8 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* This code is based on the CRAB engine
*
* Copyright (c) Arvind Raja Yadav
*
* Licensed under MIT
*
*/
#include "crab/event/trigger.h"
namespace Crab {
using namespace pyrodactyl::event;
void Trigger::load(rapidxml::xml_node<char> *node) {
Common::String ty;
loadStr(ty, "type", node);
// Should we throw a warning about missing fields? Depends on the type of trigger
bool echoOp = true, echoTar = false, echoSub = true;
if (ty == "obj")
_type = TRIG_OBJ;
else if (ty == "opinion") {
_type = TRIG_OPINION;
echoTar = true;
} else if (ty == "loc") {
_type = TRIG_LOC;
echoOp = false;
} else if (ty == "item") {
_type = TRIG_ITEM;
echoOp = false;
} else if (ty == "rect") {
_type = TRIG_RECT;
echoOp = false;
} else if (ty == "stat") {
_type = TRIG_STAT;
echoTar = true;
} else if (ty == "diff") {
_type = TRIG_DIFF;
echoSub = false;
} else if (ty == "trait") {
_type = TRIG_TRAIT;
} else
_type = TRIG_VAR;
loadStr(_target, "target", node, echoTar);
loadStr(_subject, "subject", node, echoSub);
loadStr(_operation, "operation", node, echoOp);
loadStr(_val, "val", node);
Common::String str;
loadStr(str, "rel", node, false);
if (str == "or")
_rel = OP_OR;
else
_rel = OP_AND;
loadStr(str, "prefix", node, false);
if (str == "!")
_negate = true;
else
_negate = false;
}
bool Trigger::evaluate(int lhs, int rhs) {
if (_operation == ">" && lhs > rhs)
return true;
else if (_operation == "=" && lhs == rhs)
return true;
else if (_operation == "<" && lhs < rhs)
return true;
else if (_operation == "!=" && lhs != rhs)
return true;
else if (_operation == "<=" && lhs <= rhs)
return true;
else if (_operation == ">=" && lhs >= rhs)
return true;
return false;
}
bool Trigger::evaluate(pyrodactyl::event::Info &info) {
using namespace pyrodactyl::people;
using namespace pyrodactyl::stat;
switch (_type) {
case TRIG_OBJ:
if (_operation == "p") {
if (info._talkKeyDown && info.lastPerson() == _val)
return true;
else
return false;
} else if (_operation == "status") {
PersonType ty = stringToPersonType(_val);
if (info.type(_subject) == ty)
return true;
else
return false;
} else if (_operation == "state") {
PersonState st = stringToPersonState(_val);
if (info.state(_subject) == st)
return true;
else
return false;
}
break;
case TRIG_OPINION: {
Person p;
if (info.personGet(_subject, p)) {
if (_target == "like")
return evaluate(p._opinion._val[OPI_LIKE], stringToNumber<int>(_val));
else if (_target == "fear")
return evaluate(p._opinion._val[OPI_FEAR], stringToNumber<int>(_val));
else if (_target == "respect")
return evaluate(p._opinion._val[OPI_RESPECT], stringToNumber<int>(_val));
}
}
break;
case TRIG_LOC:
return (info.curLocID() == _val);
break;
case TRIG_ITEM:
return info._inv.hasItem(_target, _subject, _val);
break;
case TRIG_RECT:
return info.collideWithTrigger(_subject, stringToNumber<int>(_val));
case TRIG_STAT: {
StatType ty = stringToStatType(_target);
int sub = 0, value = 0;
bool compareToVar = Common::find_if(_val.begin(), _val.end(), isChar) != _val.end();
info.statGet(_subject, ty, sub);
if (compareToVar)
info.statGet(_val, ty, value);
else
value = stringToNumber<int>(_val);
return evaluate(sub, value);
}
break;
case TRIG_DIFF:
return evaluate(info.ironMan(), stringToNumber<int>(_val));
case TRIG_TRAIT:
if (info.personValid(_target)) {
Person *p = &info.personGet(_target);
for (auto &i : p->_trait)
if (i._name == _val)
return true;
}
break;
case TRIG_VAR: {
int varSub = 0, varVal = 0;
bool compareToVar = Common::find_if(_val.begin(), _val.end(), isChar) != _val.end();
info.varGet(_subject, varSub);
if (compareToVar)
info.varGet(_val, varVal);
else
varVal = stringToNumber<int>(_val);
return evaluate(varSub, varVal);
}
break;
default:
break;
}
return false;
}
} // End of namespace Crab