Initial commit
This commit is contained in:
100
engines/crab/event/EventSeqGroup.cpp
Normal file
100
engines/crab/event/EventSeqGroup.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/* 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/EventSeqGroup.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::event;
|
||||
|
||||
void EventSeqGroup::endSeq(const uint &id) {
|
||||
_seq.erase(id);
|
||||
_end.push_back(id);
|
||||
}
|
||||
|
||||
void EventSeqGroup::addSeq(const uint &id, const Common::Path &path) {
|
||||
_seq[id].load(path);
|
||||
}
|
||||
|
||||
bool EventSeqGroup::eventInProgress(const uint &id) {
|
||||
return _seq.contains(id) && _seq[id].eventInProgress();
|
||||
}
|
||||
|
||||
GameEvent *EventSeqGroup::curEvent(const uint &id) {
|
||||
return _seq[id].currentEvent();
|
||||
}
|
||||
|
||||
void EventSeqGroup::nextEvent(const uint &id, Info &info, const Common::String &playerId,
|
||||
Common::Array<EventResult> &result, Common::Array<EventSeqInfo> &endSeq, const int choice) {
|
||||
return _seq[id].nextEvent(info, playerId, result, endSeq, choice);
|
||||
}
|
||||
|
||||
void EventSeqGroup::internalEvents(Info &info) {
|
||||
for (auto &it : _seq)
|
||||
it._value.internalEvents(info);
|
||||
}
|
||||
|
||||
bool EventSeqGroup::activeSeq(uint &activeSeq) {
|
||||
for (auto &i : _seq) {
|
||||
if (i._value.eventInProgress()) {
|
||||
activeSeq = i._key;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
activeSeq = UINT_MAX;
|
||||
return false;
|
||||
}
|
||||
|
||||
void EventSeqGroup::saveState(rapidxml::xml_document<> &doc, rapidxml::xml_node<char> *root) {
|
||||
for (const auto &i : _end) {
|
||||
rapidxml::xml_node<char> *child = doc.allocate_node(rapidxml::node_element, "end");
|
||||
child->value(g_engine->_stringPool->get(i));
|
||||
root->append_node(child);
|
||||
}
|
||||
|
||||
for (auto &i : _seq)
|
||||
i._value.saveState(doc, root, g_engine->_stringPool->get(i._key));
|
||||
}
|
||||
|
||||
void EventSeqGroup::loadState(rapidxml::xml_node<char> *node) {
|
||||
for (rapidxml::xml_node<char> *i = node->first_node("end"); i != nullptr; i = i->next_sibling("end"))
|
||||
endSeq(stringToNumber<uint>(i->value()));
|
||||
|
||||
for (auto n = node->first_node("set"); n != nullptr; n = n->next_sibling("set"))
|
||||
if (n->first_attribute("name") != nullptr) {
|
||||
uint id = stringToNumber<uint>(n->first_attribute("name")->value());
|
||||
if (_seq.contains(id))
|
||||
_seq[id].loadState(n);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
72
engines/crab/event/EventSeqGroup.h
Normal file
72
engines/crab/event/EventSeqGroup.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_EVENTSEQGROUP_H
|
||||
#define CRAB_EVENTSEQGROUP_H
|
||||
|
||||
#include "crab/event/EventSequence.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
class EventSeqGroup {
|
||||
typedef Common::HashMap<uint, EventSequence> SeqMap;
|
||||
|
||||
// The event sequences in this group
|
||||
SeqMap _seq;
|
||||
|
||||
// The sequences that have ended in this group
|
||||
Common::Array<uint> _end;
|
||||
|
||||
public:
|
||||
EventSeqGroup() {}
|
||||
~EventSeqGroup() {}
|
||||
|
||||
void addSeq(const uint &id, const Common::Path &path);
|
||||
void endSeq(const uint &id);
|
||||
bool eventInProgress(const uint &id);
|
||||
bool activeSeq(uint &activeSeq);
|
||||
|
||||
GameEvent *curEvent(const uint &id);
|
||||
void nextEvent(const uint &id, Info &info, const Common::String &playerId, Common::Array<EventResult> &result,
|
||||
Common::Array<EventSeqInfo> &endSeq, const int choice = -1);
|
||||
|
||||
void internalEvents(Info &info);
|
||||
|
||||
void saveState(rapidxml::xml_document<> &doc, rapidxml::xml_node<char> *root);
|
||||
void loadState(rapidxml::xml_node<char> *node);
|
||||
};
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_EVENTSEQGROUP_H
|
||||
148
engines/crab/event/EventSequence.cpp
Normal file
148
engines/crab/event/EventSequence.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/* 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/XMLDoc.h"
|
||||
#include "crab/event/EventSequence.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::event;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Load
|
||||
//------------------------------------------------------------------------
|
||||
void EventSequence::load(const Common::Path &filename) {
|
||||
XMLDoc conf(filename);
|
||||
if (conf.ready()) {
|
||||
rapidxml::xml_node<char> *node = conf.doc()->first_node("events");
|
||||
for (auto n = node->first_node("event"); n != nullptr; n = n->next_sibling("event")) {
|
||||
GameEvent e(n);
|
||||
_events.push_back(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Check for events happening
|
||||
//------------------------------------------------------------------------
|
||||
void EventSequence::internalEvents(pyrodactyl::event::Info &info) {
|
||||
for (const auto &nxe : _next) {
|
||||
if (nxe < _events.size()) {
|
||||
if (_events[nxe]._trig.evaluate(info)) {
|
||||
_eventInProgress = true;
|
||||
_cur = nxe;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Go to next event
|
||||
//------------------------------------------------------------------------
|
||||
void EventSequence::nextEvent(pyrodactyl::event::Info &info, const Common::String &player_id, Common::Array<EventResult> &result,
|
||||
Common::Array<EventSeqInfo> &end_seq, int NextEventChoice) {
|
||||
bool sync = false;
|
||||
_eventInProgress = false;
|
||||
|
||||
// Execute all effects associated with the event
|
||||
for (auto &i : _events[_cur]._effect)
|
||||
if (i.execute(info, player_id, result, end_seq))
|
||||
sync = true;
|
||||
|
||||
// Play a notification sound
|
||||
using namespace pyrodactyl::music;
|
||||
|
||||
if (info._sound._repDec)
|
||||
g_engine->_musicManager->playEffect(g_engine->_musicManager->_repDec, 0);
|
||||
else if (info._sound._repInc)
|
||||
g_engine->_musicManager->playEffect(g_engine->_musicManager->_repInc, 0);
|
||||
else if (info._sound._notify)
|
||||
g_engine->_musicManager->playEffect(g_engine->_musicManager->_notify, 0);
|
||||
|
||||
info._sound._notify = false;
|
||||
info._sound._repDec = false;
|
||||
info._sound._repInc = false;
|
||||
|
||||
if (!result.empty() || sync) {
|
||||
EventResult r;
|
||||
r._type = ER_SYNC;
|
||||
result.push_back(r);
|
||||
}
|
||||
|
||||
// Clear the next event list
|
||||
_next.clear();
|
||||
|
||||
// Add the next event to the event list
|
||||
if (NextEventChoice != -1)
|
||||
_next.push_back(NextEventChoice);
|
||||
else {
|
||||
for (const auto &i : _events[_cur]._next)
|
||||
_next.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Save the state of the object
|
||||
//------------------------------------------------------------------------
|
||||
void EventSequence::saveState(rapidxml::xml_document<char> &doc, rapidxml::xml_node<char> *root, const char *name) {
|
||||
rapidxml::xml_node<char> *seqnode = doc.allocate_node(rapidxml::node_element, "set");
|
||||
|
||||
// Write current event id and name to node
|
||||
seqnode->append_attribute(doc.allocate_attribute("name", name));
|
||||
seqnode->append_attribute(doc.allocate_attribute("current", g_engine->_stringPool->get(_cur)));
|
||||
|
||||
// Prepare strings of next events and write them
|
||||
for (uint i = 0; i < _next.size(); i++) {
|
||||
rapidxml::xml_node<char> *child = doc.allocate_node(rapidxml::node_element, "next");
|
||||
child->value(g_engine->_stringPool->get(_next[i]));
|
||||
seqnode->append_node(child);
|
||||
}
|
||||
|
||||
root->append_node(seqnode);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Load the state of the object
|
||||
//------------------------------------------------------------------------
|
||||
void EventSequence::loadState(rapidxml::xml_node<char> *node) {
|
||||
rapidxml::xml_attribute<char> *curid = node->first_attribute("current");
|
||||
if (curid != nullptr)
|
||||
_cur = stringToNumber<uint>(curid->value());
|
||||
|
||||
_next.clear();
|
||||
for (auto n = node->first_node("next"); n != nullptr; n = n->next_sibling("next"))
|
||||
_next.push_back(stringToNumber<uint>(n->value()));
|
||||
|
||||
if (_next.empty())
|
||||
_next.push_back(0);
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
89
engines/crab/event/EventSequence.h
Normal file
89
engines/crab/event/EventSequence.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_EVENTSEQUENCE_H
|
||||
#define CRAB_EVENTSEQUENCE_H
|
||||
|
||||
#include "crab/event/gameevent.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
class EventSequence {
|
||||
Common::Array<GameEvent> _events;
|
||||
bool _eventInProgress;
|
||||
|
||||
// The event currently in execution - updated only when all trigger conditions are met in InternalEvents
|
||||
uint _cur;
|
||||
|
||||
// The events that can happen next - these are updated when the cur event is over
|
||||
// This means cur and next operate in an alternating way
|
||||
// scan next until find event, make it cur, end cur and update next, repeat
|
||||
Common::Array<uint> _next;
|
||||
|
||||
public:
|
||||
EventSequence() {
|
||||
_eventInProgress = false;
|
||||
_next.push_back(0);
|
||||
_cur = 0;
|
||||
}
|
||||
|
||||
~EventSequence() {}
|
||||
|
||||
GameEvent *currentEvent() {
|
||||
return &_events[_cur];
|
||||
}
|
||||
|
||||
// See if we should trigger any event
|
||||
void internalEvents(pyrodactyl::event::Info &info);
|
||||
void nextEvent(Info &info, const Common::String &playerId, Common::Array<EventResult> &result,
|
||||
Common::Array<EventSeqInfo> &endSeq, int nextEventChoice = -1);
|
||||
|
||||
bool eventInProgress() {
|
||||
return _eventInProgress;
|
||||
}
|
||||
|
||||
void eventInProgress(bool val) {
|
||||
_eventInProgress = val;
|
||||
}
|
||||
|
||||
// Load and save
|
||||
void load(const Common::Path &filename);
|
||||
|
||||
void saveState(rapidxml::xml_document<char> &doc, rapidxml::xml_node<char> *root, const char *name);
|
||||
void loadState(rapidxml::xml_node<char> *node);
|
||||
};
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_EVENTSEQUENCE_H
|
||||
398
engines/crab/event/GameEventInfo.cpp
Normal file
398
engines/crab/event/GameEventInfo.cpp
Normal file
@@ -0,0 +1,398 @@
|
||||
/* 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/XMLDoc.h"
|
||||
#include "crab/event/eventstore.h"
|
||||
#include "crab/event/GameEventInfo.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
bool isChar(char c) {
|
||||
if (c >= '0' && c <= '9')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
using namespace pyrodactyl::people;
|
||||
using namespace pyrodactyl::event;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Load from xml
|
||||
//------------------------------------------------------------------------
|
||||
void Info::load(rapidxml::xml_node<char> *node) {
|
||||
if (nodeValid("people", node)) {
|
||||
rapidxml::xml_node<char> *pnode = node->first_node("people");
|
||||
|
||||
_stem.load(pnode->first_attribute("templates")->value());
|
||||
|
||||
XMLDoc conf(pnode->first_attribute("list")->value());
|
||||
if (conf.ready()) {
|
||||
rapidxml::xml_node<char> *cnode = conf.doc()->first_node("characters");
|
||||
if (nodeValid(cnode)) {
|
||||
loadNum(OPINION_MIN, "op_min", cnode);
|
||||
loadNum(OPINION_MAX, "op_max", cnode);
|
||||
|
||||
for (auto n = cnode->first_node("group"); n != nullptr; n = n->next_sibling("group"))
|
||||
loadPeople(n->value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeValid("objective", node))
|
||||
_journal.load(node->first_node("objective")->first_attribute("layout")->value());
|
||||
|
||||
if (nodeValid("inventory", node)) {
|
||||
rapidxml::xml_node<char> *inode = node->first_node("inventory");
|
||||
_inv.load(inode->first_attribute("layout")->value());
|
||||
}
|
||||
|
||||
curLocID(node->first_node("level")->first_attribute("start")->value());
|
||||
_inv.itemFile(node->first_node("item")->first_attribute("list")->value());
|
||||
}
|
||||
|
||||
void Info::loadPeople(const Common::Path &filename) {
|
||||
XMLDoc conf(filename);
|
||||
if (conf.ready()) {
|
||||
rapidxml::xml_node<char> *node = conf.doc()->first_node("people");
|
||||
if (nodeValid(node)) {
|
||||
for (auto n = node->first_node(); n != nullptr; n = n->next_sibling()) {
|
||||
Common::String str;
|
||||
loadStr(str, "id", n);
|
||||
_people[str].load(n, _stem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Get/Set information about object type
|
||||
//------------------------------------------------------------------------
|
||||
void Info::type(const Common::String &id, const PersonType &val) {
|
||||
if (_people.contains(id))
|
||||
_people[id]._type = val;
|
||||
}
|
||||
|
||||
PersonType Info::type(const Common::String &id) {
|
||||
if (_people.contains(id))
|
||||
return _people[id]._type;
|
||||
|
||||
return PE_NEUTRAL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Get/Set information about object state
|
||||
//------------------------------------------------------------------------
|
||||
void Info::state(const Common::String &id, const PersonState &val) {
|
||||
if (_people.contains(id))
|
||||
_people[id]._state = val;
|
||||
}
|
||||
|
||||
PersonState Info::state(const Common::String &id) {
|
||||
if (_people.contains(id))
|
||||
return _people[id]._state;
|
||||
|
||||
return PST_NORMAL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Get/Set information about variables
|
||||
//------------------------------------------------------------------------
|
||||
bool Info::varGet(const Common::String &name, int &val) {
|
||||
if (!_var.contains(name))
|
||||
return false;
|
||||
else
|
||||
val = _var[name];
|
||||
return true;
|
||||
}
|
||||
|
||||
void Info::varSet(const Common::String &name, const Common::String &val) {
|
||||
int varVal = 0;
|
||||
bool assignToVar = Common::find_if(val.begin(), val.end(), isChar) != val.end();
|
||||
|
||||
if (assignToVar)
|
||||
varGet(val, varVal);
|
||||
else
|
||||
varVal = stringToNumber<int>(val);
|
||||
|
||||
_var[name] = varVal;
|
||||
}
|
||||
|
||||
void Info::varAdd(const Common::String &name, const int &val) {
|
||||
if (!_var.contains(name))
|
||||
varSet(name, 0);
|
||||
|
||||
_var[name] += val;
|
||||
}
|
||||
|
||||
void Info::varSub(const Common::String &name, const int &val) {
|
||||
if (!_var.contains(name))
|
||||
varSet(name, 0);
|
||||
|
||||
_var[name] -= val;
|
||||
}
|
||||
|
||||
void Info::varMul(const Common::String &name, const int &val) {
|
||||
if (!_var.contains(name))
|
||||
varSet(name, 0);
|
||||
|
||||
_var[name] *= val;
|
||||
}
|
||||
|
||||
void Info::varDiv(const Common::String &name, const int &val) {
|
||||
if (!_var.contains(name))
|
||||
varSet(name, 0);
|
||||
|
||||
_var[name] /= val;
|
||||
}
|
||||
|
||||
void Info::varDel(const Common::String &name) {
|
||||
_var.erase(name);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Get/Set person traits
|
||||
//------------------------------------------------------------------------
|
||||
void Info::traitAdd(const Common::String &perId, const int &traitId) {
|
||||
if (personValid(perId)) { // Valid person id
|
||||
if (traitId >= 0 && (uint)traitId < g_engine->_eventStore->_trait.size()) { // Valid trait id
|
||||
// Check for duplicate traits, DONT award anything if duplicate found
|
||||
Person *p = &personGet(perId);
|
||||
|
||||
for (const auto &i : p->_trait)
|
||||
if (i._id == traitId)
|
||||
return;
|
||||
|
||||
p->_trait.push_back(g_engine->_eventStore->_trait[traitId]);
|
||||
|
||||
g_engine->_eventStore->setAchievement(g_engine->_eventStore->_trait[traitId]._id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Info::traitDel(const Common::String &perId, const int &traitId) {
|
||||
if (personValid(perId)) { // Valid person id
|
||||
if (traitId > 0 && (uint)traitId < g_engine->_eventStore->_trait.size()) { // Valid trait id
|
||||
Person *p = &personGet(perId);
|
||||
|
||||
for (auto j = p->_trait.begin(); j != p->_trait.end(); ++j) {
|
||||
if (j->_id == traitId) {
|
||||
p->_trait.erase(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Get/Set information about object opinion
|
||||
//------------------------------------------------------------------------
|
||||
bool Info::opinionGet(const Common::String &name, const pyrodactyl::people::OpinionType &type, int &val) {
|
||||
if (!_people.contains(name))
|
||||
return false;
|
||||
|
||||
val = _people[name]._opinion._val[type];
|
||||
return true;
|
||||
}
|
||||
|
||||
void Info::opinionChange(const Common::String &name, const pyrodactyl::people::OpinionType &type, int val) {
|
||||
if (_people.contains(name))
|
||||
_people[name]._opinion.change(type, val);
|
||||
}
|
||||
|
||||
void Info::opinionSet(const Common::String &name, const pyrodactyl::people::OpinionType &type, int val) {
|
||||
if (_people.contains(name))
|
||||
_people[name]._opinion.set(type, val);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Get/Set information about object stats
|
||||
//------------------------------------------------------------------------
|
||||
bool Info::statGet(const Common::String &name, const pyrodactyl::stat::StatType &type, int &num) {
|
||||
if (!_people.contains(name))
|
||||
return false;
|
||||
|
||||
num = _people[name]._stat._val[type]._cur;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Info::statSet(const Common::String &name, const pyrodactyl::stat::StatType &type, const int &num) {
|
||||
if (_people.contains(name))
|
||||
_people[name]._stat.set(type, num);
|
||||
}
|
||||
|
||||
void Info::statChange(const Common::String &name, const pyrodactyl::stat::StatType &type, const int &num) {
|
||||
if (_people.contains(name))
|
||||
_people[name]._stat.change(type, num);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Get person object
|
||||
//------------------------------------------------------------------------
|
||||
bool Info::personGet(const Common::String &id, pyrodactyl::people::Person &p) {
|
||||
if (!_people.contains(id))
|
||||
return false;
|
||||
|
||||
p = _people[id];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Info::personValid(const Common::String &id) {
|
||||
return _people.contains(id);
|
||||
}
|
||||
|
||||
pyrodactyl::people::Person &Info::personGet(const Common::String &id) {
|
||||
// Make sure to check PersonValid before doing this!
|
||||
// Only use this to change parts of an object
|
||||
return _people[id];
|
||||
}
|
||||
|
||||
bool Info::collideWithTrigger(const Common::String &id, int rectIndex) {
|
||||
if (_people.contains(id)) {
|
||||
for (const auto &i : _people[id]._trig)
|
||||
if (i == rectIndex)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Replace all #values with their appropriate names in a string
|
||||
//------------------------------------------------------------------------
|
||||
void Info::insertName(Common::String &msg) {
|
||||
// We scan the dialog for #id values, which we convert to actual NPC names
|
||||
for (uint i = 0; i < msg.size(); ++i) {
|
||||
// The # symbol indicates that the next string until an end character needs to be replaced by the name
|
||||
if (msg[i] == '#') {
|
||||
// The position we want to start from, and the length of the substring
|
||||
uint start = i, end = i + 1, len = 0;
|
||||
|
||||
// First make sure # wasn't the end of the string
|
||||
for (; end < msg.size(); ++end, ++len)
|
||||
if (msg[end] == ',' || msg[end] == '.' || msg[end] == '!' || msg[end] == ' ' ||
|
||||
msg[end] == '?' || msg[end] == '-' || msg[end] == '\'' || msg[end] == '\"')
|
||||
break;
|
||||
|
||||
if (end < msg.size()) {
|
||||
// We use start+1 here because # isn't part of the id
|
||||
Common::String s = msg.substr(start + 1, len);
|
||||
|
||||
// We use length+1 here because otherwise it lets the last character stay in dialog
|
||||
if (personValid(s))
|
||||
msg.replace(start, len + 1, personGet(s)._name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Common::String Info::getName(const Common::String &id) {
|
||||
if (personValid(id))
|
||||
return personGet(id)._name;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Save and load object state
|
||||
//------------------------------------------------------------------------
|
||||
void Info::saveState(rapidxml::xml_document<> &doc, rapidxml::xml_node<char> *root) {
|
||||
for (const auto &v : _var) {
|
||||
rapidxml::xml_node<char> *child = doc.allocate_node(rapidxml::node_element, "var");
|
||||
child->append_attribute(doc.allocate_attribute("id", v._key.c_str()));
|
||||
child->append_attribute(doc.allocate_attribute("val", g_engine->_stringPool->get(v._value)));
|
||||
root->append_node(child);
|
||||
}
|
||||
|
||||
for (auto &p : _people)
|
||||
p._value.saveState(doc, root);
|
||||
|
||||
rapidxml::xml_node<char> *childUnr = doc.allocate_node(rapidxml::node_element, "unread");
|
||||
|
||||
saveBool(_unread._inventory, "inventory", doc, childUnr);
|
||||
saveBool(_unread._journal, "journal", doc, childUnr);
|
||||
saveBool(_unread._trait, "trait", doc, childUnr);
|
||||
saveBool(_unread._map, "map", doc, childUnr);
|
||||
|
||||
root->append_node(childUnr);
|
||||
|
||||
rapidxml::xml_node<char> *child_img = doc.allocate_node(rapidxml::node_element, "img");
|
||||
child_img->append_attribute(doc.allocate_attribute("index", g_engine->_stringPool->get(_playerImg)));
|
||||
root->append_node(child_img);
|
||||
|
||||
rapidxml::xml_node<char> *child_money = doc.allocate_node(rapidxml::node_element, "money");
|
||||
child_money->append_attribute(doc.allocate_attribute("var", _moneyVar.c_str()));
|
||||
root->append_node(child_money);
|
||||
|
||||
_journal.saveState(doc, root);
|
||||
_inv.saveState(doc, root);
|
||||
}
|
||||
|
||||
void Info::loadState(rapidxml::xml_node<char> *node) {
|
||||
for (rapidxml::xml_node<char> *v = node->first_node("var"); v != nullptr; v = v->next_sibling("var"))
|
||||
_var[v->first_attribute("id")->value()] = stringToNumber<int>(v->first_attribute("val")->value());
|
||||
|
||||
for (rapidxml::xml_node<char> *p = node->first_node("object"); p != nullptr; p = p->next_sibling("object")) {
|
||||
Common::String id;
|
||||
loadStr(id, "id", p);
|
||||
_people[id].loadState(p);
|
||||
}
|
||||
|
||||
if (nodeValid("unread", node)) {
|
||||
rapidxml::xml_node<char> *unrnode = node->first_node("unread");
|
||||
loadBool(_unread._inventory, "inventory", unrnode);
|
||||
loadBool(_unread._journal, "journal", unrnode);
|
||||
loadBool(_unread._trait, "trait", unrnode);
|
||||
loadBool(_unread._map, "map", unrnode);
|
||||
}
|
||||
|
||||
if (nodeValid("img", node))
|
||||
loadNum(_playerImg, "index", node->first_node("img"));
|
||||
|
||||
if (nodeValid("money", node))
|
||||
loadStr(_moneyVar, "var", node->first_node("money"));
|
||||
|
||||
_journal.loadState(node);
|
||||
_inv.loadState(node);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Calculate UI positions after change in screen size
|
||||
//------------------------------------------------------------------------
|
||||
void Info::setUI() {
|
||||
_journal.setUI();
|
||||
_inv.setUI();
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
243
engines/crab/event/GameEventInfo.h
Normal file
243
engines/crab/event/GameEventInfo.h
Normal file
@@ -0,0 +1,243 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_GAMEEVENTINFO_H
|
||||
#define CRAB_GAMEEVENTINFO_H
|
||||
|
||||
#include "crab/stat/StatTemplate.h"
|
||||
#include "crab/ui/Inventory.h"
|
||||
#include "crab/ui/journal.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
bool isChar(char c);
|
||||
|
||||
class Info {
|
||||
// The characters in the game
|
||||
pyrodactyl::people::PersonMap _people;
|
||||
|
||||
// The stat templates used in declaring person objects
|
||||
pyrodactyl::stat::StatTemplates _stem;
|
||||
|
||||
// The variables set by the events so far
|
||||
typedef Common::HashMap<Common::String, int> VarMap;
|
||||
VarMap _var;
|
||||
|
||||
// The last object player interacted with
|
||||
Common::String _lastobj;
|
||||
|
||||
// Is the game Iron Man or not?
|
||||
// Iron man means only one save - no reloading
|
||||
bool _ironman;
|
||||
|
||||
// The player's current location
|
||||
struct PlayerLoc {
|
||||
// id of the player's current location
|
||||
Common::String _id;
|
||||
|
||||
// The name of the player's current location
|
||||
Common::String _name;
|
||||
|
||||
PlayerLoc() {}
|
||||
} _loc;
|
||||
|
||||
// This image changes to reflect the playable character
|
||||
int _playerImg;
|
||||
|
||||
void loadPeople(const Common::Path &filename);
|
||||
|
||||
public:
|
||||
// The player's one stop shop for objectives and lore
|
||||
pyrodactyl::ui::Journal _journal;
|
||||
|
||||
// The current player inventory
|
||||
pyrodactyl::ui::Inventory _inv;
|
||||
|
||||
// This structure keeps track of unread indicators
|
||||
struct UnreadData {
|
||||
bool _inventory, _journal, _trait, _map;
|
||||
|
||||
UnreadData() {
|
||||
_inventory = false;
|
||||
_journal = false;
|
||||
_trait = true;
|
||||
_map = false;
|
||||
}
|
||||
} _unread;
|
||||
|
||||
// This is the variable corresponding to money that is drawn
|
||||
Common::String _moneyVar;
|
||||
|
||||
// Has the player pressed the talk key
|
||||
bool _talkKeyDown;
|
||||
|
||||
// Used so we only play one sound per event
|
||||
struct NotifySounds {
|
||||
bool _notify, _repInc, _repDec;
|
||||
|
||||
NotifySounds() {
|
||||
_notify = false;
|
||||
_repInc = false;
|
||||
_repDec = false;
|
||||
}
|
||||
} _sound;
|
||||
|
||||
Info() {
|
||||
Init();
|
||||
}
|
||||
|
||||
~Info() {}
|
||||
|
||||
void Init() {
|
||||
_lastobj = "";
|
||||
_ironman = false;
|
||||
_playerImg = 0;
|
||||
_talkKeyDown = false;
|
||||
}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
|
||||
// Person related stuff
|
||||
void type(const Common::String &id, const pyrodactyl::people::PersonType &val);
|
||||
pyrodactyl::people::PersonType type(const Common::String &id);
|
||||
|
||||
void state(const Common::String &id, const pyrodactyl::people::PersonState &val);
|
||||
pyrodactyl::people::PersonState state(const Common::String &id);
|
||||
|
||||
// Opinion
|
||||
bool opinionGet(const Common::String &name, const pyrodactyl::people::OpinionType &type, int &val);
|
||||
void opinionSet(const Common::String &name, const pyrodactyl::people::OpinionType &type, int val);
|
||||
void opinionChange(const Common::String &name, const pyrodactyl::people::OpinionType &type, int val);
|
||||
|
||||
// Stats
|
||||
bool statGet(const Common::String &name, const pyrodactyl::stat::StatType &type, int &num);
|
||||
void statSet(const Common::String &name, const pyrodactyl::stat::StatType &type, const int &num);
|
||||
void statChange(const Common::String &name, const pyrodactyl::stat::StatType &type, const int &num);
|
||||
|
||||
// Variables
|
||||
bool varGet(const Common::String &name, int &val);
|
||||
void varSet(const Common::String &name, const Common::String &val);
|
||||
void varAdd(const Common::String &name, const int &val);
|
||||
void varSub(const Common::String &name, const int &val);
|
||||
void varMul(const Common::String &name, const int &val);
|
||||
void varDiv(const Common::String &name, const int &val);
|
||||
void varDel(const Common::String &name);
|
||||
|
||||
// The trait functions
|
||||
void traitAdd(const Common::String &perId, const int &traitId);
|
||||
void traitDel(const Common::String &perId, const int &traitId);
|
||||
|
||||
// Player character button
|
||||
void playerImg(const int &val) {
|
||||
_playerImg = val;
|
||||
}
|
||||
|
||||
int playerImg() {
|
||||
return _playerImg;
|
||||
}
|
||||
|
||||
Common::String curLocID() {
|
||||
return _loc._id;
|
||||
}
|
||||
|
||||
void curLocID(const Common::String &id) {
|
||||
_loc._id = id;
|
||||
}
|
||||
|
||||
Common::String curLocName() {
|
||||
return _loc._name;
|
||||
}
|
||||
|
||||
void curLocName(const Common::String &name) {
|
||||
_loc._name = name;
|
||||
}
|
||||
|
||||
// Player stuff
|
||||
Common::String lastPerson() {
|
||||
return _lastobj;
|
||||
}
|
||||
|
||||
void lastPerson(const Common::String &name) {
|
||||
_lastobj = name;
|
||||
}
|
||||
|
||||
// Return the variable map for stuff like visibility checks
|
||||
VarMap &mapGet() {
|
||||
return _var;
|
||||
}
|
||||
|
||||
bool personGet(const Common::String &id, pyrodactyl::people::Person &p);
|
||||
|
||||
bool personValid(const Common::String &id);
|
||||
pyrodactyl::people::Person &personGet(const Common::String &id);
|
||||
|
||||
// Is an object colliding with a trigger area
|
||||
bool collideWithTrigger(const Common::String &id, int rectIndex);
|
||||
|
||||
// Replace all #values with their appropriate names in a string
|
||||
void insertName(Common::String &msg);
|
||||
Common::String getName(const Common::String &id);
|
||||
|
||||
// Draw the inventory
|
||||
void invDraw(const Common::String &id) {
|
||||
if (_var.contains(_moneyVar))
|
||||
_inv.draw(_people[id], _var[_moneyVar]);
|
||||
else
|
||||
_inv.draw(_people[id], 0);
|
||||
}
|
||||
|
||||
// Get whether game is iron man or not
|
||||
bool ironMan() {
|
||||
return _ironman;
|
||||
}
|
||||
|
||||
void ironMan(const bool &val) {
|
||||
_ironman = val;
|
||||
}
|
||||
|
||||
void loadIronMan(rapidxml::xml_node<char> *node) {
|
||||
Common::String str;
|
||||
loadStr(str, "diff", node);
|
||||
_ironman = (str == "Iron Man");
|
||||
}
|
||||
|
||||
void saveState(rapidxml::xml_document<> &doc, rapidxml::xml_node<char> *root);
|
||||
void loadState(rapidxml::xml_node<char> *node);
|
||||
|
||||
void setUI();
|
||||
};
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_GAMEEVENTINFO_H
|
||||
73
engines/crab/event/changeval.h
Normal file
73
engines/crab/event/changeval.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_CHANGEVAL_H
|
||||
#define CRAB_CHANGEVAL_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "crab/loaders.h"
|
||||
#include "crab/people/opinion.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::people;
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
struct ChangeVal {
|
||||
// The person whose opinion is changed
|
||||
Common::String _id;
|
||||
|
||||
// How much does opinion change?
|
||||
int _val[pyrodactyl::people::OPI_TOTAL];
|
||||
|
||||
ChangeVal() {
|
||||
_val[OPI_LIKE] = 0;
|
||||
_val[OPI_RESPECT] = 0;
|
||||
_val[OPI_FEAR] = 0;
|
||||
}
|
||||
|
||||
ChangeVal(rapidxml::xml_node<char> *node) : ChangeVal() {
|
||||
load(node);
|
||||
}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node) {
|
||||
loadStr(_id, "id", node);
|
||||
loadNum(_val[OPI_LIKE], "like", node);
|
||||
loadNum(_val[OPI_RESPECT], "respect", node);
|
||||
loadNum(_val[OPI_FEAR], "fear", node);
|
||||
}
|
||||
};
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_CHANGEVAL_H
|
||||
55
engines/crab/event/conversationdata.cpp
Normal file
55
engines/crab/event/conversationdata.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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/conversationdata.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::event;
|
||||
|
||||
void ReplyChoice::load(rapidxml::xml_node<char> *node) {
|
||||
loadStr(_text, "text", node);
|
||||
loadNum(_tone, "tone", node);
|
||||
loadNum(_nextid, "next", node);
|
||||
|
||||
if (nodeValid("unlock", node, false))
|
||||
_unlock.load(node->first_node("unlock"));
|
||||
|
||||
if (nodeValid("change", node, false))
|
||||
for (auto n = node->first_node("change"); n != nullptr; n = n->next_sibling("change"))
|
||||
_change.push_back(n);
|
||||
}
|
||||
|
||||
void ConversationData::load(rapidxml::xml_node<char> *node) {
|
||||
for (auto n = node->first_node("reply"); n != nullptr; n = n->next_sibling("reply"))
|
||||
_reply.push_back(n);
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
83
engines/crab/event/conversationdata.h
Normal file
83
engines/crab/event/conversationdata.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_CONVERSATIONDATA_H
|
||||
#define CRAB_CONVERSATIONDATA_H
|
||||
|
||||
#include "crab/event/changeval.h"
|
||||
#include "crab/event/triggerset.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
struct ReplyChoice {
|
||||
// The text for the reply
|
||||
Common::String _text;
|
||||
|
||||
// The tone of the response
|
||||
uint _tone;
|
||||
|
||||
// The next event id
|
||||
uint _nextid;
|
||||
|
||||
// The conditions to unlock this choice
|
||||
TriggerSet _unlock;
|
||||
|
||||
// The changes to opinion that are possible for this reply
|
||||
// All NPCs affected by this conversation
|
||||
Common::Array<ChangeVal> _change;
|
||||
|
||||
ReplyChoice() {
|
||||
_tone = 0;
|
||||
_nextid = 0;
|
||||
}
|
||||
|
||||
ReplyChoice(rapidxml::xml_node<char> *node) : ReplyChoice() {
|
||||
load(node);
|
||||
}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
};
|
||||
|
||||
struct ConversationData {
|
||||
// The set of replies
|
||||
Common::Array<ReplyChoice> _reply;
|
||||
|
||||
ConversationData() {}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
};
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_CONVERSATIONDATA_H
|
||||
289
engines/crab/event/effect.cpp
Normal file
289
engines/crab/event/effect.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
/* 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
|
||||
127
engines/crab/event/effect.h
Normal file
127
engines/crab/event/effect.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_EFFECT_H
|
||||
#define CRAB_EFFECT_H
|
||||
|
||||
#include "crab/loaders.h"
|
||||
#include "crab/event/GameEventInfo.h"
|
||||
#include "crab/people/person.h"
|
||||
#include "crab/rapidxml/rapidxml.hpp"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
enum EventResultType {
|
||||
ER_NONE, // Do nothing
|
||||
ER_MAP, // Change the map visible to player
|
||||
ER_DEST, // Add or remove a destination on world map
|
||||
ER_IMG, // Change the character button image
|
||||
ER_TRAIT, // Add or remove a trait from a character
|
||||
ER_LEVEL, // Change level
|
||||
ER_MOVE, // Move sprite
|
||||
ER_PLAYER, // Switch the player sprite
|
||||
ER_SAVE, // Save game
|
||||
ER_SYNC, // Sync the level
|
||||
ER_QUIT // Quit to main menu
|
||||
};
|
||||
|
||||
struct EventResult {
|
||||
EventResultType _type;
|
||||
Common::String _val;
|
||||
int _x, _y;
|
||||
|
||||
EventResult() {
|
||||
_type = ER_NONE;
|
||||
_x = -1;
|
||||
_y = -1;
|
||||
}
|
||||
};
|
||||
|
||||
struct EventSeqInfo {
|
||||
bool _cur;
|
||||
Common::String _loc, _val;
|
||||
|
||||
EventSeqInfo() {
|
||||
_cur = false;
|
||||
}
|
||||
|
||||
EventSeqInfo(const bool &cur) {
|
||||
_cur = cur;
|
||||
}
|
||||
};
|
||||
|
||||
enum EffectType {
|
||||
EFF_VAR, // variable operations like adding, removing etc
|
||||
EFF_JOURNAL, // Add an objective to the player quest book
|
||||
EFF_OBJ, // Change status (hostile, coward etc), state (stand, fight, flee, KO etc) of a character
|
||||
EFF_ITEM, // Add/remove an item in the player's inventory
|
||||
EFF_LIKE, // Change opinion of a character (charm)
|
||||
EFF_FEAR, // Change opinion of a character (intimidate)
|
||||
EFF_RESPECT, // Change opinion of a character (respect)
|
||||
EFF_HEALTH, // Change health of a character
|
||||
EFF_SOUND, // Manipulate the game music
|
||||
EFF_MONEY, // Set the money variable (not its value, just that which variable is the current money variable)
|
||||
EFF_END, // End of the event sequence, remove it from active sequences
|
||||
// EFFECT DIVISION HERE
|
||||
EFF_MOVE, // Make a character move
|
||||
EFF_MAP, // Change the world map
|
||||
EFF_DEST, // Add a destination to the world map
|
||||
EFF_IMG, // Change the player button image
|
||||
EFF_TRAIT, // Add or remove a trait from a character
|
||||
EFF_LEVEL, // Load a new level
|
||||
EFF_PLAYER, // Swap the player sprite
|
||||
EFF_SAVE, // Auto save the game
|
||||
EFF_QUIT // Quit to main menu
|
||||
};
|
||||
|
||||
struct Effect {
|
||||
EffectType _type;
|
||||
Common::String _subject, _operation, _val;
|
||||
|
||||
Effect() {
|
||||
_type = EFF_VAR;
|
||||
}
|
||||
|
||||
~Effect() {}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
bool execute(pyrodactyl::event::Info &info, const Common::String &playerId,
|
||||
Common::Array<EventResult> &result, Common::Array<EventSeqInfo> &endSeq);
|
||||
|
||||
void changeOpinion(pyrodactyl::event::Info &info, pyrodactyl::people::OpinionType type);
|
||||
};
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_EFFECT_H
|
||||
102
engines/crab/event/eventstore.cpp
Normal file
102
engines/crab/event/eventstore.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/* 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/XMLDoc.h"
|
||||
#include "crab/event/eventstore.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::event;
|
||||
|
||||
void GameEventStore::addConv(rapidxml::xml_node<char> *node, uint &index) {
|
||||
ConversationData c;
|
||||
if (nodeValid("talk", node))
|
||||
c.load(node->first_node("talk"));
|
||||
|
||||
index = _con.size();
|
||||
_con.push_back(c);
|
||||
}
|
||||
|
||||
void GameEventStore::load(const Common::Path &filename) {
|
||||
|
||||
// Request current user stats from Steam
|
||||
// m_pSteamUserStats = SteamUserStats();
|
||||
|
||||
// if (m_pSteamUserStats != nullptr)
|
||||
// m_pSteamUserStats->RequestCurrentStats();
|
||||
|
||||
XMLDoc conf(filename);
|
||||
if (conf.ready()) {
|
||||
rapidxml::xml_node<char> *node = conf.doc()->first_node("store");
|
||||
|
||||
if (nodeValid("animations", node)) {
|
||||
rapidxml::xml_node<char> *animnode = node->first_node("animations");
|
||||
for (auto n = animnode->first_node("anim"); n != nullptr; n = n->next_sibling("anim"))
|
||||
_anim.push_back(n);
|
||||
}
|
||||
|
||||
if (nodeValid("tones", node)) {
|
||||
rapidxml::xml_node<char> *tonenode = node->first_node("tones");
|
||||
for (auto n = tonenode->first_node("tone"); n != nullptr; n = n->next_sibling("tone")) {
|
||||
ToneData dat;
|
||||
loadStr(dat._text, "text", n);
|
||||
_tone.push_back(dat);
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeValid("images", node)) {
|
||||
rapidxml::xml_node<char> *imgnode = node->first_node("images");
|
||||
for (auto n = imgnode->first_node("img"); n != nullptr; n = n->next_sibling("img"))
|
||||
_img.push_back(n);
|
||||
}
|
||||
|
||||
if (nodeValid("traits", node)) {
|
||||
rapidxml::xml_node<char> *traitnode = node->first_node("traits");
|
||||
for (auto n = traitnode->first_node("trait"); n != nullptr; n = n->next_sibling("trait"))
|
||||
_trait.push_back(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameEventStore::setAchievement(const int &id) {
|
||||
/*
|
||||
if (m_pSteamUserStats != nullptr)
|
||||
{
|
||||
if (id == 0)
|
||||
m_pSteamUserStats->SetAchievement("a0");
|
||||
else
|
||||
m_pSteamUserStats->SetAchievement(trait[id].id_str.c_str());
|
||||
|
||||
m_pSteamUserStats->StoreStats();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
91
engines/crab/event/eventstore.h
Normal file
91
engines/crab/event/eventstore.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_EVENTSTORE_H
|
||||
#define CRAB_EVENTSTORE_H
|
||||
|
||||
#include "crab/animation/animation.h"
|
||||
#include "crab/event/conversationdata.h"
|
||||
#include "crab/ui/StateButton.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
// This structure is responsible for storing the special data structures for events like replies, conversations
|
||||
struct GameEventStore {
|
||||
// Data related to conversation events
|
||||
Common::Array<ConversationData> _con;
|
||||
|
||||
// Data related to animations
|
||||
Common::Array<pyrodactyl::anim::Animation> _anim;
|
||||
|
||||
// Data related to the tones of a character
|
||||
struct ToneData {
|
||||
Common::String _text;
|
||||
};
|
||||
|
||||
// This sets the text the player sees as "tone" during the reply menu
|
||||
Common::Array<ToneData> _tone;
|
||||
|
||||
// We need to change player character images when switching between characters
|
||||
Common::Array<pyrodactyl::ui::StateButtonImage> _img;
|
||||
|
||||
// The set of traits for various characters
|
||||
Common::Array<pyrodactyl::people::Trait> _trait;
|
||||
|
||||
// Steam UserStats interface
|
||||
// ISteamUserStats *m_pSteamUserStats;
|
||||
|
||||
GameEventStore() {
|
||||
// Huge number to prevent lots of resizing and stuff
|
||||
_con.reserve(9999);
|
||||
|
||||
_trait.reserve(120);
|
||||
_tone.reserve(120);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_con.clear();
|
||||
_anim.clear();
|
||||
}
|
||||
|
||||
void load(const Common::Path &filename);
|
||||
|
||||
void addConv(rapidxml::xml_node<char> *node, uint &index);
|
||||
void setAchievement(const int &id);
|
||||
};
|
||||
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_EVENTSTORE_H
|
||||
91
engines/crab/event/gameevent.cpp
Normal file
91
engines/crab/event/gameevent.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/* 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/gameevent.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::event;
|
||||
using namespace pyrodactyl::people;
|
||||
|
||||
GameEvent::GameEvent() {
|
||||
_id = 0;
|
||||
_type = EVENT_DIALOG;
|
||||
_special = 0;
|
||||
_state = PST_NORMAL;
|
||||
}
|
||||
|
||||
void GameEvent::load(rapidxml::xml_node<char> *node) {
|
||||
if (!LoadEventID(_id, "id", node))
|
||||
_id = 0;
|
||||
|
||||
loadStr(_title, "title", node);
|
||||
loadStr(_dialog, "dialog", node);
|
||||
loadEnum(_state, "state", node, false);
|
||||
|
||||
Common::String type;
|
||||
loadStr(type, "type", node);
|
||||
|
||||
if (type == "dlg") {
|
||||
_type = EVENT_DIALOG;
|
||||
_special = 0;
|
||||
} else if (type == "reply") {
|
||||
_type = EVENT_REPLY;
|
||||
g_engine->_eventStore->addConv(node, _special);
|
||||
} else if (type == "animation") {
|
||||
_type = EVENT_ANIM;
|
||||
loadNum(_special, "anim", node);
|
||||
} else if (type == "silent") {
|
||||
_type = EVENT_SILENT;
|
||||
_special = 0;
|
||||
} else if (type == "text") {
|
||||
_type = EVENT_TEXT;
|
||||
_special = 0;
|
||||
} else {
|
||||
_type = EVENT_SPLASH;
|
||||
_special = 0;
|
||||
}
|
||||
|
||||
_trig.load(node);
|
||||
|
||||
_next.clear();
|
||||
for (rapidxml::xml_node<char> *i = node->first_node("next"); i != nullptr; i = i->next_sibling("next"))
|
||||
if (i->first_attribute("id") != nullptr)
|
||||
_next.push_back(stringToNumber<EventID>(i->first_attribute("id")->value()));
|
||||
|
||||
_effect.clear();
|
||||
for (rapidxml::xml_node<char> *it = node->first_node("effect"); it != nullptr; it = it->next_sibling("effect")) {
|
||||
Effect e;
|
||||
e.load(it);
|
||||
_effect.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
99
engines/crab/event/gameevent.h
Normal file
99
engines/crab/event/gameevent.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_GAMEEVENT_H
|
||||
#define CRAB_GAMEEVENT_H
|
||||
|
||||
#include "crab/event/effect.h"
|
||||
#include "crab/event/eventstore.h"
|
||||
#include "crab/people/person.h"
|
||||
#include "crab/event/triggerset.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
// An uinteger is our event id format
|
||||
typedef uint EventID;
|
||||
|
||||
// Just map loading function to number load
|
||||
#define LoadEventID loadNum
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
enum EventType {
|
||||
EVENT_DIALOG,
|
||||
EVENT_REPLY,
|
||||
EVENT_TEXT,
|
||||
EVENT_ANIM,
|
||||
EVENT_SILENT,
|
||||
EVENT_SPLASH
|
||||
};
|
||||
|
||||
struct GameEvent {
|
||||
// The event identifier
|
||||
EventID _id;
|
||||
|
||||
// The heading for the dialog spoken
|
||||
Common::String _title;
|
||||
|
||||
// The dialog spoken in the event
|
||||
Common::String _dialog;
|
||||
|
||||
// The state decides which animation is drawn in the dialog box
|
||||
pyrodactyl::people::PersonState _state;
|
||||
|
||||
// Event type and related data index
|
||||
EventType _type;
|
||||
uint _special;
|
||||
|
||||
// The variables changed/added in the event
|
||||
Common::Array<Effect> _effect;
|
||||
|
||||
// The triggers for the event
|
||||
TriggerSet _trig;
|
||||
|
||||
// The id of the next event
|
||||
Common::Array<EventID> _next;
|
||||
|
||||
GameEvent();
|
||||
|
||||
GameEvent(rapidxml::xml_node<char> *node) : GameEvent() {
|
||||
load(node);
|
||||
}
|
||||
|
||||
~GameEvent() {}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
};
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_GAMEEVENT_H
|
||||
371
engines/crab/event/gameeventmanager.cpp
Normal file
371
engines/crab/event/gameeventmanager.cpp
Normal file
@@ -0,0 +1,371 @@
|
||||
/* 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/gameeventmanager.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::people;
|
||||
using namespace pyrodactyl::event;
|
||||
using namespace pyrodactyl::level;
|
||||
using namespace pyrodactyl::image;
|
||||
using namespace pyrodactyl::ui;
|
||||
|
||||
void Manager::init() {
|
||||
_eventMap.clear();
|
||||
_activeSeq = UINT_MAX;
|
||||
_curSp = nullptr;
|
||||
_player = false;
|
||||
_curEvent = nullptr;
|
||||
_drawGame = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Load this
|
||||
//------------------------------------------------------------------------
|
||||
void Manager::load(rapidxml::xml_node<char> *node, ParagraphData &popup) {
|
||||
if (nodeValid(node)) {
|
||||
XMLDoc conf(node->first_attribute("list")->value());
|
||||
if (conf.ready()) {
|
||||
rapidxml::xml_node<char> *lnode = conf.doc()->first_node("event_list");
|
||||
for (rapidxml::xml_node<char> *loc = lnode->first_node("loc"); loc != nullptr; loc = loc->next_sibling("loc")) {
|
||||
Common::String locName;
|
||||
loadStr(locName, "name", loc);
|
||||
|
||||
for (auto n = loc->first_node("file"); n != nullptr; n = n->next_sibling("file")) {
|
||||
uint id;
|
||||
Common::Path path;
|
||||
loadNum(id, "name", n);
|
||||
loadPath(path, "path", n);
|
||||
_eventMap[locName].addSeq(id, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_activeSeq = UINT_MAX;
|
||||
|
||||
conf.load(node->first_attribute("layout")->value());
|
||||
if (conf.ready()) {
|
||||
rapidxml::xml_node<char> *layout = conf.doc()->first_node("layout");
|
||||
if (nodeValid(layout)) {
|
||||
if (nodeValid("character", layout))
|
||||
_oh.load(layout->first_node("character"));
|
||||
|
||||
if (nodeValid("popup", layout))
|
||||
popup.load(layout->first_node("popup"));
|
||||
|
||||
if (nodeValid("intro", layout))
|
||||
_intro.load(layout->first_node("intro"));
|
||||
}
|
||||
}
|
||||
|
||||
_reply.load(node->first_attribute("conversation")->value());
|
||||
|
||||
_per.load(node->first_attribute("char")->value());
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Handle events
|
||||
//------------------------------------------------------------------------
|
||||
void Manager::handleEvents(Info &info, const Common::String &playerId, Common::Event &event, HUD &hud, Level &level, Common::Array<EventResult> &result) {
|
||||
// If an event is already being performed
|
||||
if (_eventMap.contains(info.curLocID()) && _eventMap[info.curLocID()].eventInProgress(_activeSeq)) {
|
||||
switch (_curEvent->_type) {
|
||||
case EVENT_DIALOG:
|
||||
if (_oh._showJournal) {
|
||||
info._journal.handleEvents(playerId, event);
|
||||
|
||||
if (hud._back.handleEvents(event) == BUAC_LCLICK || hud._pausekey.handleEvents(event))
|
||||
_oh._showJournal = false;
|
||||
} else {
|
||||
// If journal button is select from within an event, go to the entry corresponding to that person's name
|
||||
if (_oh.handleCommonEvents(event)) {
|
||||
if (info.personValid(_curEvent->_title)) {
|
||||
Person &p = info.personGet(_curEvent->_title);
|
||||
if (p._altJournalName)
|
||||
info._journal.open(playerId, JE_PEOPLE, p._journalName);
|
||||
else
|
||||
info._journal.open(playerId, JE_PEOPLE, p._name);
|
||||
}
|
||||
}
|
||||
|
||||
if (_oh.handleDlboxEvents(event)) {
|
||||
_oh.onExit();
|
||||
_eventMap[info.curLocID()].nextEvent(_activeSeq, info, playerId, result, _endSeq);
|
||||
_oh._showJournal = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_ANIM:
|
||||
// Skip animation if key pressed or mouse pressed
|
||||
if (event.type == Common::EVENT_LBUTTONUP || event.type == Common::EVENT_RBUTTONUP)
|
||||
_eventMap[info.curLocID()].nextEvent(_activeSeq, info, playerId, result, _endSeq);
|
||||
break;
|
||||
case EVENT_REPLY:
|
||||
if (_oh._showJournal) {
|
||||
info._journal.handleEvents(playerId, event);
|
||||
|
||||
if (hud._back.handleEvents(event) == BUAC_LCLICK || hud._pausekey.handleEvents(event))
|
||||
_oh._showJournal = false;
|
||||
} else {
|
||||
// If journal button is select from within an event, go to the entry corresponding to that person's name
|
||||
if (_oh.handleCommonEvents(event))
|
||||
if (info.personValid(_curEvent->_title))
|
||||
info._journal.open(playerId, JE_PEOPLE, info.personGet(_curEvent->_title)._name);
|
||||
|
||||
unsigned int option = static_cast<unsigned int>(_reply.hoverIndex());
|
||||
const auto &replyChoice = g_engine->_eventStore->_con[_curEvent->_special]._reply;
|
||||
if (option < replyChoice.size()) {
|
||||
_intro.onEntry(replyChoice[option]._text);
|
||||
}
|
||||
|
||||
int choice = _reply.handleEvents(info, g_engine->_eventStore->_con[_curEvent->_special], _curEvent->_title, _oh, event);
|
||||
if (choice >= 0) {
|
||||
_reply.onExit();
|
||||
_eventMap[info.curLocID()].nextEvent(_activeSeq, info, playerId, result, _endSeq, choice);
|
||||
_oh._showJournal = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_TEXT:
|
||||
// If journal button is select from within an event, go to the entry corresponding to that person's name
|
||||
if (_oh.handleCommonEvents(event))
|
||||
if (info.personValid(_curEvent->_title))
|
||||
info._journal.open(playerId, JE_PEOPLE, info.personGet(_curEvent->_title)._name);
|
||||
|
||||
if (_textin.handleEvents(event))
|
||||
_eventMap[info.curLocID()].nextEvent(_activeSeq, info, playerId, result, _endSeq);
|
||||
break;
|
||||
case EVENT_SPLASH:
|
||||
if (_intro._showTraits) {
|
||||
_per.handleEvents(info, _curEvent->_title, event);
|
||||
|
||||
if (hud._back.handleEvents(event) == BUAC_LCLICK || hud._pausekey.handleEvents(event))
|
||||
_intro._showTraits = false;
|
||||
} else {
|
||||
if (_intro.handleEvents(event)) {
|
||||
_intro.onExit();
|
||||
_eventMap[info.curLocID()].nextEvent(_activeSeq, info, playerId, result, _endSeq);
|
||||
}
|
||||
if (_intro._showTraits)
|
||||
_per.Cache(info, level.playerId(), level);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
endSequence(info.curLocID());
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Internal Events
|
||||
//------------------------------------------------------------------------
|
||||
void Manager::internalEvents(Info &info, Level &level, Common::Array<EventResult> &result) {
|
||||
if (_eventMap.contains(info.curLocID())) {
|
||||
if (_eventMap[info.curLocID()].eventInProgress(_activeSeq)) {
|
||||
switch (_curEvent->_type) {
|
||||
case EVENT_DIALOG:
|
||||
// fallthrough intended
|
||||
case EVENT_REPLY:
|
||||
// fallthrough intended
|
||||
case EVENT_SPLASH:
|
||||
updateDialogBox(info, level);
|
||||
break;
|
||||
case EVENT_ANIM: {
|
||||
using namespace pyrodactyl::anim;
|
||||
|
||||
DrawType drawVal = DRAW_SAME;
|
||||
if (g_engine->_eventStore->_anim[_curEvent->_special].internalEvents(drawVal))
|
||||
_eventMap[info.curLocID()].nextEvent(_activeSeq, info, level.playerId(), result, _endSeq);
|
||||
|
||||
if (drawVal == DRAW_STOP)
|
||||
_drawGame = false;
|
||||
else if (drawVal == DRAW_START)
|
||||
_drawGame = true;
|
||||
} break;
|
||||
case EVENT_SILENT:
|
||||
_eventMap[info.curLocID()].nextEvent(_activeSeq, info, level.playerId(), result, _endSeq);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
endSequence(info.curLocID());
|
||||
} else {
|
||||
_eventMap[info.curLocID()].internalEvents(info);
|
||||
calcActiveSeq(info, level, level.camera());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::updateDialogBox(Info &info, pyrodactyl::level::Level &level) {
|
||||
_oh.internalEvents(_curEvent->_state, _curSp);
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Draw
|
||||
//------------------------------------------------------------------------
|
||||
void Manager::draw(Info &info, HUD &hud, Level &level) {
|
||||
if (_eventMap.contains(info.curLocID()) && _eventMap[info.curLocID()].eventInProgress(_activeSeq)) {
|
||||
switch (_curEvent->_type) {
|
||||
case EVENT_ANIM:
|
||||
g_engine->_eventStore->_anim[_curEvent->_special].draw();
|
||||
break;
|
||||
case EVENT_DIALOG:
|
||||
g_engine->_imageManager->dimScreen();
|
||||
if (_oh._showJournal) {
|
||||
info._journal.draw(level.playerId());
|
||||
hud._back.draw();
|
||||
} else
|
||||
_oh.draw(info, _curEvent, _curEvent->_title, _player, _curSp);
|
||||
break;
|
||||
case EVENT_REPLY:
|
||||
g_engine->_imageManager->dimScreen();
|
||||
if (_oh._showJournal) {
|
||||
info._journal.draw(level.playerId());
|
||||
hud._back.draw();
|
||||
} else {
|
||||
_oh.draw(info, _curEvent, _curEvent->_title, _player, _curSp);
|
||||
_reply.draw();
|
||||
}
|
||||
break;
|
||||
case EVENT_TEXT:
|
||||
_oh.draw(info, _curEvent, _curEvent->_title, _player, _curSp);
|
||||
_textin.draw();
|
||||
break;
|
||||
case EVENT_SPLASH:
|
||||
g_engine->_imageManager->dimScreen();
|
||||
if (_intro._showTraits) {
|
||||
_per.draw(info, _curEvent->_title);
|
||||
hud._back.draw();
|
||||
} else
|
||||
_intro.draw(info, _curEvent->_dialog, _curSp, _curEvent->_state);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Calculate the current sequence in progress
|
||||
//------------------------------------------------------------------------
|
||||
void Manager::calcActiveSeq(Info &info, pyrodactyl::level::Level &level, const Rect &camera) {
|
||||
if (_eventMap[info.curLocID()].activeSeq(_activeSeq)) {
|
||||
// Set all the pointers to the new values
|
||||
_curEvent = _eventMap[info.curLocID()].curEvent(_activeSeq);
|
||||
_oh.reset(_curEvent->_title);
|
||||
_curSp = level.getSprite(_curEvent->_title);
|
||||
|
||||
// The player character's dialog is drawn a bit differently compared to others
|
||||
_player = (_curEvent->_title == level.playerId());
|
||||
|
||||
switch (_curEvent->_type) {
|
||||
case EVENT_DIALOG:
|
||||
_oh.onEntry(_curEvent->_dialog);
|
||||
break;
|
||||
case EVENT_ANIM:
|
||||
g_engine->_eventStore->_anim[_curEvent->_special].start();
|
||||
break;
|
||||
case EVENT_REPLY:
|
||||
_reply.onEntry(_curEvent->_dialog);
|
||||
_reply.cache(info, g_engine->_eventStore->_con[_curEvent->_special]);
|
||||
break;
|
||||
case EVENT_SPLASH:
|
||||
_intro.onEntry(_curEvent->_dialog);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Get/set info
|
||||
//------------------------------------------------------------------------
|
||||
void Manager::endSequence(const Common::String &curloc) {
|
||||
if (_endSeq.empty())
|
||||
return;
|
||||
|
||||
for (const auto &i : _endSeq)
|
||||
if (i._cur)
|
||||
_eventMap[curloc].endSeq(_activeSeq);
|
||||
else if (_eventMap.contains(i._loc))
|
||||
_eventMap[i._loc].endSeq(stringToNumber<uint>(i._val));
|
||||
|
||||
_activeSeq = UINT_MAX;
|
||||
_endSeq.clear();
|
||||
}
|
||||
|
||||
bool Manager::eventInProgress() {
|
||||
if (_activeSeq == UINT_MAX)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Save the state of the object
|
||||
//------------------------------------------------------------------------
|
||||
void Manager::saveState(rapidxml::xml_document<> &doc, rapidxml::xml_node<char> *root) {
|
||||
for (auto &i : _eventMap) {
|
||||
rapidxml::xml_node<char> *child = doc.allocate_node(rapidxml::node_element, "loc");
|
||||
child->append_attribute(doc.allocate_attribute("name", i._key.c_str()));
|
||||
i._value.saveState(doc, child);
|
||||
root->append_node(child);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Load the state of the object
|
||||
//------------------------------------------------------------------------
|
||||
void Manager::loadState(rapidxml::xml_node<char> *node) {
|
||||
for (auto n = node->first_node("loc"); n != nullptr; n = n->next_sibling("loc")) {
|
||||
if (n->first_attribute("name") != nullptr) {
|
||||
Common::String name = n->first_attribute("name")->value();
|
||||
if (_eventMap.contains(name))
|
||||
_eventMap[name].loadState(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Function called when window size is changed to adjust UI
|
||||
//------------------------------------------------------------------------
|
||||
void Manager::setUI() {
|
||||
_oh.setUI();
|
||||
_reply.setUI();
|
||||
_textin.setUI();
|
||||
_per.setUI();
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
117
engines/crab/event/gameeventmanager.h
Normal file
117
engines/crab/event/gameeventmanager.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_GAMEEVENTMANAGER_H
|
||||
#define CRAB_GAMEEVENTMANAGER_H
|
||||
|
||||
#include "crab/event/EventSeqGroup.h"
|
||||
#include "crab/ui/ChapterIntro.h"
|
||||
#include "crab/ui/hud.h"
|
||||
#include "crab/ui/journal.h"
|
||||
#include "crab/ui/PersonHandler.h"
|
||||
#include "crab/ui/PersonScreen.h"
|
||||
#include "crab/ui/ReplyMenu.h"
|
||||
#include "crab/ui/textarea.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
class Manager {
|
||||
protected:
|
||||
// All the events in the game
|
||||
Common::HashMap<Common::String, EventSeqGroup> _eventMap;
|
||||
|
||||
// The currently happening or active sequence
|
||||
uint _activeSeq;
|
||||
|
||||
// THIS IS NOT THE DEFINITIVE LIST OF ENDED SEQUENCES
|
||||
// JUST A TEMPORARY LIST OF EVENT SEQUENCES TO PASS AROUND
|
||||
Common::Array<EventSeqInfo> _endSeq;
|
||||
|
||||
// The objects used to draw the dialog box and opinion bars
|
||||
pyrodactyl::ui::PersonHandler _oh;
|
||||
|
||||
// The _reply menu and the colors and font of the text
|
||||
pyrodactyl::ui::ReplyMenu _reply;
|
||||
|
||||
// The field for text input
|
||||
pyrodactyl::ui::TextArea _textin;
|
||||
|
||||
// The info for intro events
|
||||
pyrodactyl::ui::ChapterIntro _intro;
|
||||
|
||||
// Store the current event data temporarily
|
||||
GameEvent *_curEvent;
|
||||
bool _player;
|
||||
pyrodactyl::anim::Sprite *_curSp;
|
||||
|
||||
void updateDialogBox(Info &info, pyrodactyl::level::Level &level);
|
||||
|
||||
public:
|
||||
// The object used to draw the character screen
|
||||
pyrodactyl::ui::PersonScreen _per;
|
||||
|
||||
// A flag used to stop drawing the game for a better fade in/fade out experience
|
||||
bool _drawGame;
|
||||
|
||||
Manager() {
|
||||
init();
|
||||
}
|
||||
|
||||
~Manager() {}
|
||||
|
||||
void init();
|
||||
void load(rapidxml::xml_node<char> *node, pyrodactyl::ui::ParagraphData &popup);
|
||||
|
||||
void draw(Info &info, pyrodactyl::ui::HUD &hud, pyrodactyl::level::Level &level);
|
||||
|
||||
// cur_per is also updated here
|
||||
void internalEvents(Info &info, pyrodactyl::level::Level &level, Common::Array<EventResult> &result);
|
||||
|
||||
void handleEvents(Info &info, const Common::String &playerId, Common::Event &event,
|
||||
pyrodactyl::ui::HUD &hud, pyrodactyl::level::Level &level, Common::Array<EventResult> &result);
|
||||
|
||||
void calcActiveSeq(Info &info, pyrodactyl::level::Level &level, const Rect &camera);
|
||||
|
||||
void endSequence(const Common::String &curloc);
|
||||
bool eventInProgress();
|
||||
|
||||
void saveState(rapidxml::xml_document<> &doc, rapidxml::xml_node<char> *root);
|
||||
void loadState(rapidxml::xml_node<char> *node);
|
||||
|
||||
void setUI();
|
||||
};
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_GAMEEVENTMANAGER_H
|
||||
68
engines/crab/event/quest.cpp
Normal file
68
engines/crab/event/quest.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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/quest.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::event;
|
||||
|
||||
Quest::Quest(const Common::String &title, const Common::String &text, const bool &unread, const bool &marker) : _title(title) {
|
||||
_text.insert_at(0, text);
|
||||
_unread = unread;
|
||||
_marker = marker;
|
||||
}
|
||||
|
||||
void Quest::loadState(rapidxml::xml_node<char> *node) {
|
||||
loadStr(_title, "title", node);
|
||||
loadBool(_unread, "unread", node);
|
||||
loadBool(_marker, "marker", node);
|
||||
|
||||
for (rapidxml::xml_node<char> *n = node->first_node("info"); n != nullptr; n = n->next_sibling("info"))
|
||||
_text.push_back(n->value());
|
||||
}
|
||||
|
||||
void Quest::saveState(rapidxml::xml_document<> &doc, rapidxml::xml_node<char> *root) {
|
||||
rapidxml::xml_node<char> *child = doc.allocate_node(rapidxml::node_element, "quest");
|
||||
child->append_attribute(doc.allocate_attribute("title", _title.c_str()));
|
||||
|
||||
saveBool(_unread, "unread", doc, child);
|
||||
saveBool(_marker, "marker", doc, child);
|
||||
|
||||
for (const auto &i : _text) {
|
||||
rapidxml::xml_node<char> *grandchild = doc.allocate_node(rapidxml::node_element, "info");
|
||||
grandchild->value(i.c_str());
|
||||
child->append_node(grandchild);
|
||||
}
|
||||
|
||||
root->append_node(child);
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
69
engines/crab/event/quest.h
Normal file
69
engines/crab/event/quest.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_QUEST_H
|
||||
#define CRAB_QUEST_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "crab/loaders.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
struct Quest {
|
||||
// The title of the quest
|
||||
Common::String _title;
|
||||
|
||||
// The objective text, the last one being the current objective
|
||||
Common::Array<Common::String> _text;
|
||||
|
||||
// Keep track of which quests the player has read
|
||||
bool _unread;
|
||||
|
||||
// Does this quest have an associated destination marker
|
||||
bool _marker;
|
||||
|
||||
Quest() {
|
||||
_unread = true;
|
||||
_marker = false;
|
||||
}
|
||||
|
||||
Quest(const Common::String &title, const Common::String &text, const bool &unread, const bool &marker);
|
||||
|
||||
void loadState(rapidxml::xml_node<char> *node);
|
||||
void saveState(rapidxml::xml_document<char> &doc, rapidxml::xml_node<char> *root);
|
||||
};
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_QUEST_H
|
||||
204
engines/crab/event/trigger.cpp
Normal file
204
engines/crab/event/trigger.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
/* 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
|
||||
87
engines/crab/event/trigger.h
Normal file
87
engines/crab/event/trigger.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_TRIGGER_H
|
||||
#define CRAB_TRIGGER_H
|
||||
|
||||
#include "crab/event/GameEventInfo.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
enum RelOp {
|
||||
OP_AND,
|
||||
OP_OR
|
||||
};
|
||||
|
||||
enum TriggerType {
|
||||
TRIG_OBJ, // Interacting with an object, status of character (hostile, coward etc), state (stand, fight, flee, KO)
|
||||
TRIG_OPINION, // Check opinion of a character (charm / intimidate / respect)
|
||||
TRIG_LOC, // Being in a place on the map
|
||||
TRIG_ITEM, // An item is present or not
|
||||
TRIG_RECT, // A sprite is colliding with a rectangle
|
||||
TRIG_STAT, // Check any stat of an object (health, attack, defense etc)
|
||||
TRIG_DIFF, // Check the game's difficulty
|
||||
TRIG_TRAIT, // See if a character has a certain trait
|
||||
TRIG_VAR // A variable is present or not, or if it's a certain value
|
||||
};
|
||||
|
||||
struct Trigger {
|
||||
TriggerType _type;
|
||||
Common::String _target, _subject, _operation, _val;
|
||||
|
||||
// Relation to the next trigger
|
||||
RelOp _rel;
|
||||
|
||||
// Represents the Boolean ! operator
|
||||
bool _negate;
|
||||
|
||||
Trigger() {
|
||||
_type = TRIG_VAR;
|
||||
_rel = OP_AND;
|
||||
_negate = false;
|
||||
}
|
||||
|
||||
Trigger(rapidxml::xml_node<char> *node) {
|
||||
load(node);
|
||||
}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
bool evaluate(pyrodactyl::event::Info &info);
|
||||
|
||||
bool evaluate(int lhs, int rhs);
|
||||
};
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_TRIGGER_H
|
||||
73
engines/crab/event/triggerset.cpp
Normal file
73
engines/crab/event/triggerset.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/* 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/triggerset.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::event;
|
||||
|
||||
void TriggerSet::load(rapidxml::xml_node<char> *node) {
|
||||
for (rapidxml::xml_node<char> *n = node->first_node("trigger"); n != nullptr; n = n->next_sibling("trigger")) {
|
||||
Trigger t(n);
|
||||
_statement.push_back(t);
|
||||
}
|
||||
}
|
||||
|
||||
void TriggerSet::add(const Trigger &t) {
|
||||
_statement.push_back(t);
|
||||
}
|
||||
|
||||
bool TriggerSet::evaluate(pyrodactyl::event::Info &info) {
|
||||
_result = true;
|
||||
|
||||
if (_statement.empty() == false) {
|
||||
RelOp nextOp = OP_AND;
|
||||
bool curResult = false;
|
||||
|
||||
for (auto &i : _statement) {
|
||||
if (i._negate)
|
||||
curResult = !i.evaluate(info);
|
||||
else
|
||||
curResult = i.evaluate(info);
|
||||
|
||||
if (nextOp == OP_AND)
|
||||
_result = curResult && _result;
|
||||
else
|
||||
_result = curResult || _result;
|
||||
|
||||
nextOp = i._rel;
|
||||
}
|
||||
}
|
||||
|
||||
return _result;
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
79
engines/crab/event/triggerset.h
Normal file
79
engines/crab/event/triggerset.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_TRIGGERSET_H
|
||||
#define CRAB_TRIGGERSET_H
|
||||
|
||||
#include "crab/event/trigger.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace event {
|
||||
class TriggerSet {
|
||||
// The conditions needed to unlock whatever we want
|
||||
// Places where this is used - events, levels, fighting moves
|
||||
Common::Array<Trigger> _statement;
|
||||
|
||||
// Is the thing unlocked or not?
|
||||
bool _result;
|
||||
|
||||
public:
|
||||
TriggerSet() {
|
||||
_result = true;
|
||||
}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
bool evaluate(pyrodactyl::event::Info &info);
|
||||
void add(const Trigger &t);
|
||||
|
||||
bool result() {
|
||||
return _result;
|
||||
}
|
||||
|
||||
void result(bool val) {
|
||||
_result = val;
|
||||
}
|
||||
|
||||
void clear(const bool &val = true) {
|
||||
_statement.clear();
|
||||
_result = val;
|
||||
}
|
||||
|
||||
bool empty() {
|
||||
return _statement.empty();
|
||||
}
|
||||
};
|
||||
} // End of namespace event
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_TRIGGERSET_H
|
||||
Reference in New Issue
Block a user