290 lines
7.1 KiB
C++
290 lines
7.1 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/crab.h"
|
|
#include "crab/event/effect.h"
|
|
|
|
namespace Crab {
|
|
|
|
using namespace pyrodactyl::event;
|
|
using namespace pyrodactyl::music;
|
|
|
|
void Effect::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 effect
|
|
bool echoOp = true, echoSub = true, echoVal = true;
|
|
|
|
if (ty == "var")
|
|
_type = EFF_VAR;
|
|
else if (ty == "journal")
|
|
_type = EFF_JOURNAL;
|
|
else if (ty == "person")
|
|
_type = EFF_OBJ;
|
|
else if (ty == "item")
|
|
_type = EFF_ITEM;
|
|
else if (ty == "like")
|
|
_type = EFF_LIKE;
|
|
else if (ty == "fear")
|
|
_type = EFF_FEAR;
|
|
else if (ty == "respect")
|
|
_type = EFF_RESPECT;
|
|
else if (ty == STATNAME_HEALTH)
|
|
_type = EFF_HEALTH;
|
|
else if (ty == "sound")
|
|
_type = EFF_SOUND;
|
|
else if (ty == "money")
|
|
_type = EFF_MONEY;
|
|
else if (ty == "end") {
|
|
_type = EFF_END;
|
|
echoSub = false;
|
|
echoVal = false;
|
|
} else if (ty == "map")
|
|
_type = EFF_MAP;
|
|
else if (ty == "dest")
|
|
_type = EFF_DEST;
|
|
else if (ty == "img") {
|
|
_type = EFF_IMG;
|
|
echoOp = false;
|
|
echoSub = false;
|
|
} else if (ty == "trait") {
|
|
_type = EFF_TRAIT;
|
|
echoOp = false;
|
|
} else if (ty == "move") {
|
|
_type = EFF_MOVE;
|
|
echoOp = false;
|
|
} else if (ty == "level")
|
|
_type = EFF_LEVEL;
|
|
else if (ty == "player") {
|
|
_type = EFF_PLAYER;
|
|
echoOp = false;
|
|
echoSub = false;
|
|
} else if (ty == "save") {
|
|
_type = EFF_SAVE;
|
|
echoOp = false;
|
|
echoSub = false;
|
|
echoVal = false;
|
|
} else if (ty == "quit") {
|
|
_type = EFF_QUIT;
|
|
echoOp = false;
|
|
echoSub = false;
|
|
echoVal = false;
|
|
} else
|
|
_type = EFF_VAR;
|
|
|
|
loadStr(_subject, "subject", node, echoSub);
|
|
loadStr(_operation, "operation", node, echoOp);
|
|
loadStr(_val, "val", node, echoVal);
|
|
}
|
|
|
|
void Effect::changeOpinion(pyrodactyl::event::Info &info, pyrodactyl::people::OpinionType opType) {
|
|
int oldOp = 0;
|
|
|
|
// Only bother if the person exists and has a valid opinion
|
|
if (info.opinionGet(_subject, opType, oldOp)) {
|
|
if (_operation == "=")
|
|
info.opinionSet(_subject, opType, stringToNumber<int>(_val));
|
|
else if (_operation == "+")
|
|
info.opinionChange(_subject, opType, stringToNumber<int>(_val));
|
|
else if (_operation == "-")
|
|
info.opinionChange(_subject, opType, -1 * stringToNumber<int>(_val));
|
|
|
|
int newOp = 0;
|
|
info.opinionGet(_subject, opType, newOp);
|
|
|
|
if (newOp > oldOp)
|
|
info._sound._repInc = true;
|
|
else if (newOp < oldOp)
|
|
info._sound._repDec = true;
|
|
}
|
|
}
|
|
|
|
bool Effect::execute(pyrodactyl::event::Info &info, const Common::String &playerId,
|
|
Common::Array<EventResult> &result, Common::Array<EventSeqInfo> &endSeq) {
|
|
if (_type < EFF_MOVE) {
|
|
switch (_type) {
|
|
case EFF_VAR:
|
|
if (_operation == "=")
|
|
info.varSet(_subject, _val);
|
|
else if (_operation == "del")
|
|
info.varDel(_subject);
|
|
else if (_operation == "+")
|
|
info.varAdd(_subject, stringToNumber<int>(_val));
|
|
else if (_operation == "-")
|
|
info.varSub(_subject, stringToNumber<int>(_val));
|
|
else if (_operation == "*")
|
|
info.varMul(_subject, stringToNumber<int>(_val));
|
|
else if (_operation == "/")
|
|
info.varDiv(_subject, stringToNumber<int>(_val));
|
|
break;
|
|
|
|
case EFF_JOURNAL:
|
|
if (_subject == "finish")
|
|
info._journal.move(playerId, _operation, true);
|
|
else if (_subject == "start")
|
|
info._journal.move(playerId, _operation, false);
|
|
else
|
|
info._journal.add(playerId, _subject, _operation, _val);
|
|
|
|
// Update unread status of journal
|
|
info._unread._journal = true;
|
|
|
|
// used so we only play one notify sound per event
|
|
info._sound._notify = true;
|
|
break;
|
|
|
|
case EFF_OBJ:
|
|
if (_operation == "type")
|
|
info.type(_subject, pyrodactyl::people::stringToPersonType(_val));
|
|
else if (_operation == "state")
|
|
info.state(_subject, pyrodactyl::people::stringToPersonState(_val));
|
|
break;
|
|
|
|
case EFF_ITEM:
|
|
if (_operation == "del")
|
|
info._inv.delItem(_subject, _val);
|
|
else
|
|
info._inv.loadItem(_subject, _val);
|
|
|
|
// Update unread status of inventory
|
|
info._unread._inventory = true;
|
|
|
|
// used so we only play one notify sound per event
|
|
info._sound._notify = true;
|
|
break;
|
|
|
|
case EFF_LIKE:
|
|
changeOpinion(info, pyrodactyl::people::OPI_LIKE);
|
|
break;
|
|
|
|
case EFF_FEAR:
|
|
changeOpinion(info, pyrodactyl::people::OPI_FEAR);
|
|
break;
|
|
|
|
case EFF_RESPECT:
|
|
changeOpinion(info, pyrodactyl::people::OPI_RESPECT);
|
|
break;
|
|
|
|
case EFF_HEALTH: {
|
|
using namespace pyrodactyl::stat;
|
|
int num = stringToNumber<int>(_val);
|
|
|
|
if (_operation == "=")
|
|
info.statSet(_subject, STAT_HEALTH, num);
|
|
else if (_operation == "+")
|
|
info.statChange(_subject, STAT_HEALTH, num);
|
|
else if (_operation == "-")
|
|
info.statChange(_subject, STAT_HEALTH, -1 * num);
|
|
} break;
|
|
|
|
case EFF_SOUND:
|
|
if (_subject == "music") {
|
|
if (_operation == "play") {
|
|
MusicKey m = stringToNumber<MusicKey>(_val);
|
|
g_engine->_musicManager->playMusic(m);
|
|
} else if (_operation == "stop")
|
|
g_engine->_musicManager->stop();
|
|
else if (_operation == "pause")
|
|
g_engine->_musicManager->pause();
|
|
else if (_operation == "resume")
|
|
g_engine->_musicManager->resume();
|
|
} else
|
|
g_engine->_musicManager->playEffect(stringToNumber<ChunkKey>(_val), 0);
|
|
break;
|
|
|
|
case EFF_MONEY:
|
|
info._moneyVar = _val;
|
|
break;
|
|
|
|
case EFF_END:
|
|
if (_operation == "cur")
|
|
endSeq.push_back(true);
|
|
else {
|
|
EventSeqInfo seqinfo;
|
|
seqinfo._loc = _subject;
|
|
seqinfo._val = _val;
|
|
endSeq.push_back(seqinfo);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
} else {
|
|
EventResult r;
|
|
r._val = _subject;
|
|
r._x = stringToNumber<int>(_operation);
|
|
r._y = stringToNumber<int>(_val);
|
|
|
|
switch (_type) {
|
|
case EFF_MOVE:
|
|
r._type = ER_MOVE;
|
|
break;
|
|
case EFF_MAP:
|
|
r._type = ER_MAP;
|
|
break;
|
|
case EFF_DEST:
|
|
r._type = ER_DEST;
|
|
break;
|
|
case EFF_IMG:
|
|
r._type = ER_IMG;
|
|
info.playerImg(stringToNumber<int>(_val));
|
|
break;
|
|
case EFF_TRAIT:
|
|
r._type = ER_TRAIT;
|
|
info._unread._trait = true;
|
|
info._sound._notify = true;
|
|
break;
|
|
case EFF_LEVEL:
|
|
r._type = ER_LEVEL;
|
|
break;
|
|
case EFF_PLAYER:
|
|
r._type = ER_PLAYER;
|
|
break;
|
|
case EFF_SAVE:
|
|
r._type = ER_SAVE;
|
|
break;
|
|
case EFF_QUIT:
|
|
r._type = ER_QUIT;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
result.push_back(r);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
} // End of namespace Crab
|