mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
This fixes annpying portability issue, generating tons of warnings, since printing int64s is still platform-dependent.
826 lines
21 KiB
C++
826 lines
21 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "common/debug.h"
|
|
#include "common/stream.h"
|
|
|
|
#include "qdengine/qdengine.h"
|
|
#include "qdengine/qd_fwd.h"
|
|
|
|
#include "qdengine/parser/xml_tag_buffer.h"
|
|
#include "qdengine/parser/qdscr_parser.h"
|
|
|
|
#include "qdengine/qdcore/qd_trigger_element.h"
|
|
#include "qdengine/qdcore/qd_trigger_chain.h"
|
|
#include "qdengine/qdcore/qd_video.h"
|
|
#include "qdengine/qdcore/qd_minigame.h"
|
|
#include "qdengine/qdcore/qd_music_track.h"
|
|
#include "qdengine/qdcore/qd_game_scene.h"
|
|
#include "qdengine/qdcore/qd_grid_zone.h"
|
|
#include "qdengine/qdcore/qd_game_object_state.h"
|
|
#include "qdengine/qdcore/qd_game_object_animated.h"
|
|
#include "qdengine/qdcore/qd_named_object_indexer.h"
|
|
#include "qdengine/qdcore/qd_game_dispatcher.h"
|
|
|
|
namespace QDEngine {
|
|
|
|
qdTriggerLink::qdTriggerLink(qdTriggerElementPtr p, int tp)
|
|
: _element(p),
|
|
_element_ID(qdTriggerElement::INVALID_ID),
|
|
_type(tp),
|
|
_auto_restart(false) {
|
|
if (_element)
|
|
_element_ID = _element->ID();
|
|
|
|
set_status(LINK_INACTIVE);
|
|
}
|
|
|
|
qdTriggerLink::qdTriggerLink() : _element(NULL),
|
|
_element_ID(qdTriggerElement::INVALID_ID),
|
|
_type(0),
|
|
_auto_restart(false) {
|
|
set_status(LINK_INACTIVE);
|
|
}
|
|
|
|
bool qdTriggerLink::load_script(const xml::tag *p) {
|
|
for (xml::tag::subtag_iterator it = p->subtags_begin(); it != p->subtags_end(); ++it) {
|
|
xml::tag_buffer buf(*it);
|
|
switch (it->ID()) {
|
|
case QDSCR_ID:
|
|
set_element_ID(buf.get_int());
|
|
break;
|
|
case QDSCR_TYPE:
|
|
_type = buf.get_int();
|
|
break;
|
|
case QDSCR_TRIGGER_ELEMENT_LINK_AUTO_RESTART:
|
|
if (buf.get_int())
|
|
_auto_restart = true;
|
|
else
|
|
_auto_restart = false;
|
|
break;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerLink::save_script(Common::WriteStream &fh, int indent) const {
|
|
for (int i = 0; i < indent; i++) {
|
|
fh.writeString("\t");
|
|
}
|
|
fh.writeString("<link");
|
|
|
|
if (_element) {
|
|
fh.writeString(Common::String::format(" ID=\"%d\"", _element->ID()));
|
|
}
|
|
|
|
if (_type) {
|
|
fh.writeString(Common::String::format(" type=\"%d\"", _type));
|
|
}
|
|
|
|
if (_auto_restart) {
|
|
fh.writeString(" auto_restart=\"1\"");
|
|
}
|
|
|
|
fh.writeString("/>\r\n");
|
|
return true;
|
|
}
|
|
|
|
qdTriggerElement::qdTriggerElement() : _object(NULL),
|
|
_ID(0),
|
|
_is_active(false),
|
|
_status(TRIGGER_EL_INACTIVE) {
|
|
}
|
|
|
|
qdTriggerElement::qdTriggerElement(qdNamedObject *p) : _object(p),
|
|
_ID(0),
|
|
_is_active(false),
|
|
_status(TRIGGER_EL_INACTIVE) {
|
|
p->add_trigger_reference();
|
|
}
|
|
|
|
qdTriggerElement::~qdTriggerElement() {
|
|
if (_object) _object->remove_trigger_reference();
|
|
|
|
_parents.clear();
|
|
_children.clear();
|
|
}
|
|
|
|
bool qdTriggerElement::check_external_conditions(int link_type) {
|
|
if (_parents.empty()) return true;
|
|
|
|
for (auto &it : _parents) {
|
|
if (it.type() == link_type && it.element()->status() != TRIGGER_EL_DONE) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::check_internal_conditions() {
|
|
if (!_object) return true;
|
|
|
|
if (qdConditionalObject * p = dynamic_cast<qdConditionalObject * >(_object)) {
|
|
if (p->trigger_can_start())
|
|
return p->check_conditions();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
qdTriggerLink *qdTriggerElement::find_child_link(qdTriggerElementConstPtr ptrChild) {
|
|
qdTriggerLinkList::iterator itr = Common::find(_children.begin(), _children.end(), ptrChild);
|
|
|
|
if (itr != _children.end())
|
|
return &*itr;
|
|
return NULL;
|
|
}
|
|
|
|
qdTriggerLink *qdTriggerElement::find_child_link(int child_id) {
|
|
for (qdTriggerLinkList::iterator it = _children.begin(); it != _children.end(); ++it) {
|
|
if (it->element()->ID() == child_id)
|
|
return &*it;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
qdTriggerLink *qdTriggerElement::find_parent_link(qdTriggerElementConstPtr ptrParent) {
|
|
qdTriggerLinkList::iterator itr = Common::find(_parents.begin(), _parents.end(), ptrParent);
|
|
|
|
if (itr != _parents.end())
|
|
return &*itr;
|
|
return NULL;
|
|
}
|
|
|
|
qdTriggerLink *qdTriggerElement::find_parent_link(int parent_id) {
|
|
for (qdTriggerLinkList::iterator it = _parents.begin(); it != _parents.end(); ++it) {
|
|
if (it->element()->ID() == parent_id)
|
|
return &*it;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool qdTriggerElement::is_parent(qdTriggerElementConstPtr p) {
|
|
for (auto &it : _parents) {
|
|
if (it.element() == p) return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool qdTriggerElement::is_child(qdTriggerElementConstPtr p) {
|
|
for (auto &it : _children) {
|
|
if (it.element() == p) return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool qdTriggerElement::add_parent(qdTriggerElementPtr p, int link_type) {
|
|
if (p == this || is_parent(p)) return false;
|
|
_parents.push_back(qdTriggerLink(p, link_type));
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::add_child(qdTriggerElementPtr p, int link_type, bool auto_restart) {
|
|
if (p == this || is_child(p)) return false;
|
|
_children.push_back(qdTriggerLink(p, link_type));
|
|
if (auto_restart)
|
|
_children.back().toggle_auto_restart(true);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::remove_parent(qdTriggerElementPtr p) {
|
|
for (auto it = _parents.begin(); it != _parents.end(); it++) {
|
|
if ((*it).element() == p) {
|
|
_parents.erase(it);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool qdTriggerElement::remove_child(qdTriggerElementPtr p) {
|
|
for (auto it = _children.begin(); it != _children.end(); it++) {
|
|
if ((*it).element() == p) {
|
|
_children.erase(it);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool qdTriggerElement::load_script(const xml::tag *p) {
|
|
for (xml::tag::subtag_iterator it = p->subtags_begin(); it != p->subtags_end(); ++it) {
|
|
switch (it->ID()) {
|
|
case QDSCR_ID:
|
|
set_id(xml::tag_buffer(*it).get_int());
|
|
break;
|
|
case QDSCR_NAMED_OBJECT: {
|
|
qdNamedObjectReference ref;
|
|
ref.load_script(&*it);
|
|
retrieve_object(ref);
|
|
}
|
|
break;
|
|
case QDSCR_TRIGGER_START_ELEMENT:
|
|
if (xml::tag_buffer(*it).get_int())
|
|
_is_active = true;
|
|
else
|
|
_is_active = false;
|
|
break;
|
|
case QDSCR_TRIGGER_ELEMENT_PARENT_LINKS:
|
|
load_links_script(&*it, true);
|
|
break;
|
|
case QDSCR_TRIGGER_ELEMENT_CHILD_LINKS:
|
|
load_links_script(&*it, false);
|
|
break;
|
|
}
|
|
}
|
|
|
|
set_status(TRIGGER_EL_INACTIVE);
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::load_links_script(const xml::tag *p, bool load_parents) {
|
|
qdTriggerLinkList &lst = (load_parents) ? _parents : _children;
|
|
|
|
int size = 0;
|
|
for (xml::tag::subtag_iterator it = p->subtags_begin(); it != p->subtags_end(); ++it) {
|
|
if (it->ID() == QDSCR_TRIGGER_ELEMENT_LINK)
|
|
size++;
|
|
}
|
|
|
|
if (size)
|
|
lst.resize(size);
|
|
|
|
int link_idx = 0;
|
|
for (xml::tag::subtag_iterator it = p->subtags_begin(); it != p->subtags_end(); ++it) {
|
|
if (it->ID() == QDSCR_TRIGGER_ELEMENT_LINK) {
|
|
if (link_idx < size)
|
|
lst[link_idx++].load_script(&*it);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::save_script(Common::WriteStream &fh, int indent) const {
|
|
for (int i = 0; i < indent; i++) {
|
|
fh.writeString("\t");
|
|
}
|
|
|
|
if (_ID == ROOT_ID) {
|
|
fh.writeString("<trigger_chain_root");
|
|
} else {
|
|
fh.writeString(Common::String::format("<trigger_element ID=\"%d\"", _ID));
|
|
}
|
|
|
|
if (_is_active) {
|
|
fh.writeString(" start_element=\"1\"");
|
|
}
|
|
|
|
fh.writeString(">\r\n");
|
|
|
|
if (_object) {
|
|
qdNamedObjectReference ref(_object);
|
|
ref.save_script(fh, indent + 1);
|
|
}
|
|
|
|
if (_parents.size()) {
|
|
for (int i = 0; i <= indent; i++) {
|
|
fh.writeString("\t");
|
|
}
|
|
fh.writeString("<parent_links>\r\n");
|
|
|
|
for (auto &it: _parents) {
|
|
it.save_script(fh, indent + 2);
|
|
}
|
|
|
|
for (int i = 0; i <= indent; i++) {
|
|
fh.writeString("\t");
|
|
}
|
|
fh.writeString("</parent_links>\r\n");
|
|
}
|
|
|
|
if (_children.size()) {
|
|
for (int i = 0; i <= indent; i++) {
|
|
fh.writeString("\t");
|
|
}
|
|
fh.writeString("<child_links>\r\n");
|
|
|
|
for (auto &it : _children) {
|
|
it.save_script(fh, indent + 2);
|
|
}
|
|
|
|
for (int i = 0; i <= indent; i++) {
|
|
fh.writeString("\t");
|
|
}
|
|
fh.writeString("</child_links>\r\n");
|
|
}
|
|
|
|
for (int i = 0; i < indent; i++) {
|
|
fh.writeString("\t");
|
|
}
|
|
if (_ID == ROOT_ID) {
|
|
fh.writeString("</trigger_chain_root>\r\n");
|
|
} else {
|
|
fh.writeString("</trigger_element>\r\n");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::retrieve_object(const qdNamedObjectReference &ref) {
|
|
if (qdGameDispatcher * dsp = qdGameDispatcher::get_dispatcher()) {
|
|
if (_object) _object->remove_trigger_reference();
|
|
_object = dsp->get_named_object(&ref);
|
|
|
|
if (!_object) {
|
|
qdNamedObjectReference &r = qdNamedObjectIndexer::instance().add_reference((qdNamedObject *&)_object);
|
|
r = ref;
|
|
|
|
#ifdef __QD_DEBUG_ENABLE__
|
|
debugC(3, kDebugLog, "qdTriggerElement::retrieve_object() failed");
|
|
debugC(3, kDebugLog, "%s", ref.toString().c_str());
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
_object->add_trigger_reference();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool qdTriggerElement::retrieve_link_elements(qdTriggerChain *p) {
|
|
bool result = true;
|
|
|
|
for (qdTriggerLinkList::iterator it = _parents.begin(); it != _parents.end(); ++it) {
|
|
if (!it->element()) {
|
|
if (qdTriggerElementPtr el = p->search_element(it->element_ID())) {
|
|
it->set_element(el);
|
|
} else {
|
|
debugC(3, kDebugLog, "parent link element not found: %d->%d", ID(), it->element_ID());
|
|
result = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (qdTriggerLinkList::iterator it = _children.begin(); it != _children.end(); ++it) {
|
|
if (!it->element()) {
|
|
if (qdTriggerElementPtr el = p->search_element(it->element_ID())) {
|
|
it->set_element(el);
|
|
} else {
|
|
debugC(3, kDebugLog, "child link element not found: %d->%d", ID(), it->element_ID());
|
|
result = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool qdTriggerElement::quant(float dt) {
|
|
bool ret = false;
|
|
|
|
for (auto &it : _children) {
|
|
if (it.status() == qdTriggerLink::LINK_ACTIVE) {
|
|
if (it.element()->conditions_quant(it.type())) {
|
|
if (!it.auto_restart())
|
|
it.set_status(qdTriggerLink::LINK_DONE);
|
|
ret = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void qdTriggerElement::start() {
|
|
if (qdConditionalObject * p = dynamic_cast<qdConditionalObject *>(_object)) {
|
|
switch (p->trigger_start()) {
|
|
case qdConditionalObject::TRIGGER_START_ACTIVATE:
|
|
set_status(TRIGGER_EL_WORKING);
|
|
|
|
for (qdTriggerLinkList::iterator it = _parents.begin(); it != _parents.end(); ++it) {
|
|
if (qdTriggerLink * lp = it->element()->find_child_link(this)) {
|
|
if (lp->status() == qdTriggerLink::LINK_ACTIVE) {
|
|
it->element()->activate_links(this);
|
|
it->element()->deactivate_links(this);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case qdConditionalObject::TRIGGER_START_WAIT:
|
|
set_status(TRIGGER_EL_WAITING);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else
|
|
set_status(TRIGGER_EL_WAITING);
|
|
}
|
|
|
|
bool qdTriggerElement::conditions_quant(int link_type) {
|
|
switch (_status) {
|
|
case TRIGGER_EL_DONE:
|
|
case TRIGGER_EL_INACTIVE:
|
|
if (check_external_conditions(link_type) && check_internal_conditions() && _object) {
|
|
if (qdCondition::successful_click())
|
|
qdGameDispatcher::get_dispatcher()->drop_flag(qdGameDispatcher::CLICK_FAILED_FLAG);
|
|
if (qdCondition::successful_object_click())
|
|
qdGameDispatcher::get_dispatcher()->drop_flag(qdGameDispatcher::OBJECT_CLICK_FAILED_FLAG);
|
|
start();
|
|
} else {
|
|
if (_object && _object->named_object_type() == QD_NAMED_OBJECT_OBJ_STATE) {
|
|
qdGameObjectState *p = static_cast<qdGameObjectState *>(_object);
|
|
if (p->has_text() && p->check_flag(qdGameObjectState::QD_OBJ_STATE_FLAG_DIALOG_PHRASE)) {
|
|
if (qdGameDispatcher * gp = qd_get_game_dispatcher())
|
|
gp->add_dialog_state(p);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case TRIGGER_EL_WAITING:
|
|
if (_object && _object->named_object_type() == QD_NAMED_OBJECT_OBJ_STATE) {
|
|
qdGameObjectState *p = static_cast<qdGameObjectState *>(_object);
|
|
qdGameObjectAnimated *obj = static_cast<qdGameObjectAnimated *>(_object->owner());
|
|
|
|
switch (obj->state_status(p)) {
|
|
case qdGameObjectAnimated::STATE_INACTIVE:
|
|
set_status(TRIGGER_EL_INACTIVE);
|
|
break;
|
|
case qdGameObjectAnimated::STATE_ACTIVE:
|
|
case qdGameObjectAnimated::STATE_DONE:
|
|
set_status(TRIGGER_EL_WORKING);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else
|
|
set_status(TRIGGER_EL_WORKING);
|
|
|
|
if (status() == TRIGGER_EL_WORKING) {
|
|
for (qdTriggerLinkList::iterator it = _parents.begin(); it != _parents.end(); ++it) {
|
|
if (qdTriggerLink * lp = it->element()->find_child_link(this)) {
|
|
if (lp->status() != qdTriggerLink::LINK_INACTIVE) {
|
|
it->element()->activate_links(this);
|
|
it->element()->deactivate_links(this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case TRIGGER_EL_WORKING:
|
|
if (_object && _object->named_object_type() == QD_NAMED_OBJECT_OBJ_STATE) {
|
|
qdGameObjectState *p = static_cast<qdGameObjectState *>(_object);
|
|
qdGameObjectAnimated *obj = static_cast<qdGameObjectAnimated *>(_object->owner());
|
|
|
|
switch (obj->state_status(p)) {
|
|
case qdGameObjectAnimated::STATE_INACTIVE:
|
|
set_status(TRIGGER_EL_DONE);
|
|
break;
|
|
case qdGameObjectAnimated::STATE_ACTIVE:
|
|
break;
|
|
case qdGameObjectAnimated::STATE_DONE:
|
|
obj->handle_state_end();
|
|
set_status(TRIGGER_EL_DONE);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else
|
|
set_status(TRIGGER_EL_DONE);
|
|
|
|
if (_status == TRIGGER_EL_DONE) {
|
|
for (auto &it : _parents)
|
|
it.element()->deactivate_link(this);
|
|
|
|
for (auto &it : _children) {
|
|
it.activate();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
break;
|
|
// case TRIGGER_EL_DONE:
|
|
// break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool qdTriggerElement::activate_links(qdTriggerElementPtr child) {
|
|
int link_type = -1;
|
|
for (auto &it : _children) {
|
|
if (it.element() == child) {
|
|
link_type = it.type();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (link_type == -1) return false;
|
|
|
|
for (auto &it : _children) {
|
|
if (it.type() == link_type) {
|
|
if (it.element() != child && it.status() == qdTriggerLink::LINK_INACTIVE) {
|
|
it.activate();
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::deactivate_links(qdTriggerElementPtr child) {
|
|
int link_type = -1;
|
|
for (auto &it : _children) {
|
|
if (it.element() == child) {
|
|
link_type = it.type();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (link_type == -1) return false;
|
|
|
|
for (auto &it : _children) {
|
|
if (it.type() != link_type) {
|
|
it.deactivate();
|
|
// it->element()->set_status(qdTriggerElement::TRIGGER_EL_INACTIVE);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::deactivate_link(qdTriggerElementPtr child) {
|
|
for (auto &it : _children) {
|
|
if (it.element() == child) {
|
|
it.deactivate();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool qdTriggerElement::debug_set_active() {
|
|
set_status(TRIGGER_EL_INACTIVE);
|
|
|
|
for (qdTriggerLinkList::iterator it = _children.begin(); it != _children.end(); ++it) {
|
|
if (it->element()->status() == TRIGGER_EL_DONE && !it->element()->is_active())
|
|
it->element()->debug_set_inactive();
|
|
}
|
|
|
|
for (qdTriggerLinkList::iterator it = _parents.begin(); it != _parents.end(); ++it) {
|
|
it->element()->set_child_link_status(this, qdTriggerLink::LINK_ACTIVE);
|
|
it->element()->set_status(TRIGGER_EL_DONE);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::debug_set_inactive() {
|
|
for (qdTriggerLinkList::iterator it = _parents.begin(); it != _parents.end(); ++it)
|
|
it->element()->set_child_link_status(this, qdTriggerLink::LINK_INACTIVE);
|
|
|
|
set_status(TRIGGER_EL_INACTIVE);
|
|
|
|
for (qdTriggerLinkList::iterator it = _children.begin(); it != _children.end(); ++it) {
|
|
if (it->element()->status() == TRIGGER_EL_DONE && !it->element()->is_active())
|
|
it->element()->debug_set_inactive();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::debug_set_done() {
|
|
for (qdTriggerLinkList::iterator it = _parents.begin(); it != _parents.end(); ++it)
|
|
it->element()->set_child_link_status(this, qdTriggerLink::LINK_DONE);
|
|
|
|
set_status(TRIGGER_EL_DONE);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::set_child_link_status(qdTriggerElementConstPtr child, qdTriggerLink::LinkStatus st) {
|
|
if (qdTriggerLink * p = find_child_link(child)) {
|
|
if (!p->auto_restart() || st == qdTriggerLink::LINK_ACTIVE) {
|
|
p->set_status(st);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool qdTriggerElement::set_parent_link_status(qdTriggerElementConstPtr parent, qdTriggerLink::LinkStatus st) {
|
|
if (qdTriggerLink * p = find_parent_link(parent)) {
|
|
p->set_status(st);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool qdTriggerElement::load_data(Common::SeekableReadStream &fh, int saveVersion) {
|
|
debugC(5, kDebugSave, " qdTriggerElement::load_data before: %d", (int)fh.pos());
|
|
char st = fh.readByte();
|
|
set_status(ElementStatus(st));
|
|
|
|
for (auto &it : _parents) {
|
|
st = fh.readByte();
|
|
it.set_status(qdTriggerLink::LinkStatus(st));
|
|
}
|
|
|
|
for (auto &it : _children) {
|
|
st = fh.readByte();
|
|
it.set_status(qdTriggerLink::LinkStatus(st));
|
|
}
|
|
|
|
debugC(5, kDebugSave, " qdTriggerElement::load_data after: %d", (int)fh.pos());
|
|
return true;
|
|
}
|
|
|
|
bool qdTriggerElement::save_data(Common::WriteStream &fh) const {
|
|
debugC(5, kDebugSave, " qdTriggerElement::save_data before: %d", (int)fh.pos());
|
|
/* switch(_status){
|
|
case TRIGGER_EL_INACTIVE:
|
|
for(qdTriggerLinkList::const_iterator it = _parents.begin(); it != _parents.end(); ++it){
|
|
if(it->status() != qdTriggerLink::LINK_INACTIVE)
|
|
break;
|
|
}
|
|
for(qdTriggerLinkList::const_iterator it = _children.begin(); it != _children.end(); ++it){
|
|
if(it->status() != qdTriggerLink::LINK_INACTIVE)
|
|
break;
|
|
}
|
|
fh < char(TRIGGER_EL_INACTIVE_ALL);
|
|
return true;
|
|
case TRIGGER_EL_DONE:
|
|
for(qdTriggerLinkList::const_iterator it = _parents.begin(); it != _parents.end(); ++it){
|
|
if(it->status() != qdTriggerLink::LINK_DONE)
|
|
break;
|
|
}
|
|
for(qdTriggerLinkList::const_iterator it = _children.begin(); it != _children.end(); ++it){
|
|
if(it->status() != qdTriggerLink::LINK_DONE)
|
|
break;
|
|
}
|
|
fh < char(TRIGGER_EL_DONE_ALL);
|
|
return true;
|
|
}*/
|
|
|
|
fh.writeByte(_status);
|
|
|
|
for (auto &it : _parents) {
|
|
fh.writeByte(it.status());
|
|
}
|
|
|
|
for (auto &it : _children) {
|
|
fh.writeByte(it.status());
|
|
}
|
|
|
|
debugC(5, kDebugSave, " qdTriggerElement::save_data after: %d", (int)fh.pos());
|
|
return true;
|
|
}
|
|
|
|
void qdTriggerLink::activate() {
|
|
set_status(LINK_ACTIVE);
|
|
|
|
// if(_element && _element->status() != qdTriggerElement::TRIGGER_EL_INACTIVE)
|
|
// _element->set_status(qdTriggerElement::TRIGGER_EL_INACTIVE);
|
|
|
|
// debugC(3, kDebugLog, "%p", this);
|
|
}
|
|
|
|
void qdTriggerLink::deactivate() {
|
|
if (_status == LINK_ACTIVE) {
|
|
if (!auto_restart())
|
|
set_status(LINK_INACTIVE);
|
|
#ifdef __QD_DEBUG_ENABLE__
|
|
else
|
|
debugC(3, kDebugLog, "%s", toString().c_str());
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
Common::String qdTriggerLink::toString() {
|
|
Common::String res;
|
|
|
|
if (element()) {
|
|
if (qdNamedObject *p = element()->object()) {
|
|
res = Common::String::format("->type %d ", type());
|
|
|
|
switch (status()) {
|
|
case qdTriggerLink::LINK_ACTIVE:
|
|
res += " on ";
|
|
break;
|
|
case qdTriggerLink::LINK_INACTIVE:
|
|
res += " off ";
|
|
break;
|
|
case qdTriggerLink::LINK_DONE:
|
|
res += " cut ";
|
|
break;
|
|
}
|
|
|
|
if (p->named_object_type() == QD_NAMED_OBJECT_OBJ_STATE) {
|
|
if (p->owner() && p->owner()->name())
|
|
res += Common::String((char *)transCyrillic(p->owner()->name()));
|
|
}
|
|
res += Common::String((char *)transCyrillic(p->name()));
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
Common::String qdNamedObjectReference::toString() const {
|
|
Common::String res;
|
|
|
|
for (int i = 0; i < num_levels(); i++) {
|
|
if (i)
|
|
res += Common::String("::");
|
|
res += Common::String((char *)transCyrillic(object_name(num_levels() - i - 1)));
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
void qdTriggerElement::set_status(ElementStatus st) {
|
|
_status = st;
|
|
}
|
|
|
|
void qdTriggerElement::reset() {
|
|
for (qdTriggerLinkList::iterator it = _parents.begin(); it != _parents.end(); ++it)
|
|
it->set_status(qdTriggerLink::LINK_INACTIVE);
|
|
for (qdTriggerLinkList::iterator it = _children.begin(); it != _children.end(); ++it)
|
|
it->set_status(qdTriggerLink::LINK_INACTIVE);
|
|
|
|
set_status(TRIGGER_EL_INACTIVE);
|
|
}
|
|
|
|
void qdTriggerElement::deactivate(const qdNamedObject *ignore_object) {
|
|
for (qdTriggerLinkList::iterator it = _parents.begin(); it != _parents.end(); ++it) {
|
|
if (!ignore_object || it->element()->object() != ignore_object) {
|
|
if (!it->auto_restart())
|
|
it->set_status(qdTriggerLink::LINK_INACTIVE);
|
|
}
|
|
}
|
|
for (qdTriggerLinkList::iterator it = _children.begin(); it != _children.end(); ++it) {
|
|
if (!ignore_object || it->element()->object() != ignore_object) {
|
|
if (!it->auto_restart())
|
|
it->set_status(qdTriggerLink::LINK_INACTIVE);
|
|
}
|
|
}
|
|
|
|
set_status(TRIGGER_EL_INACTIVE);
|
|
|
|
for (qdTriggerLinkList::iterator it = _parents.begin(); it != _parents.end(); ++it) {
|
|
if (!ignore_object || it->element()->object() != ignore_object)
|
|
it->element()->set_child_link_status(this, qdTriggerLink::LINK_INACTIVE);
|
|
}
|
|
}
|
|
|
|
bool qdTriggerElement::add_object_trigger_reference() {
|
|
if (_object) {
|
|
_object->add_trigger_reference();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool qdTriggerElement::clear_object_trigger_references() {
|
|
if (_object) {
|
|
_object->clear_trigger_references();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
} // namespace QDEngine
|