mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
383 lines
10 KiB
C++
383 lines
10 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/>.
|
|
*
|
|
*/
|
|
|
|
|
|
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
|
#include "common/debug.h"
|
|
#include "common/stream.h"
|
|
|
|
#include "qdengine/qd_fwd.h"
|
|
#include "qdengine/parser/xml_tag_buffer.h"
|
|
#include "qdengine/parser/qdscr_parser.h"
|
|
#include "qdengine/qdcore/qd_conditional_object.h"
|
|
#include "qdengine/qdcore/qd_game_scene.h"
|
|
|
|
|
|
namespace QDEngine {
|
|
|
|
#ifdef _QUEST_EDITOR
|
|
qdConditionalObject::ConditionsMode qdConditionalObject::backup_mode_ = qdConditionalObject::CONDITIONS_OR;
|
|
qdConditionalObject::condition_groups_container_t qdConditionalObject::groups_backup_;
|
|
qdConditionalObject::conditions_container_t qdConditionalObject::backup_;
|
|
|
|
std::list<qdConditionalObject *> qdConditionalObject::objects_list_;
|
|
bool qdConditionalObject::enable_objects_list_ = false;
|
|
#endif
|
|
|
|
qdConditionalObject::qdConditionalObject() : conditions_mode_(CONDITIONS_OR) {
|
|
#ifdef _QUEST_EDITOR
|
|
if (enable_objects_list_)
|
|
objects_list_.push_back(this);
|
|
#endif
|
|
}
|
|
|
|
qdConditionalObject::qdConditionalObject(const qdConditionalObject &obj) : qdNamedObject(obj),
|
|
conditions_mode_(obj.conditions_mode_),
|
|
conditions_(obj.conditions_),
|
|
condition_groups_(obj.condition_groups_) {
|
|
#ifdef _QUEST_EDITOR
|
|
if (enable_objects_list_)
|
|
objects_list_.push_back(this);
|
|
#endif
|
|
}
|
|
|
|
qdConditionalObject::~qdConditionalObject() {
|
|
#ifdef _QUEST_EDITOR
|
|
if (enable_objects_list_) {
|
|
std::list<qdConditionalObject *>::iterator it = std::find(objects_list_.begin(), objects_list_.end(), this);
|
|
if (it != objects_list_.end())
|
|
objects_list_.erase(it);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
qdConditionalObject &qdConditionalObject::operator = (const qdConditionalObject &obj) {
|
|
if (this == &obj) return *this;
|
|
|
|
*static_cast<qdNamedObject *>(this) = obj;
|
|
|
|
conditions_mode_ = obj.conditions_mode_;
|
|
conditions_ = obj.conditions_;
|
|
condition_groups_ = obj.condition_groups_;
|
|
|
|
return *this;
|
|
}
|
|
|
|
int qdConditionalObject::add_condition(const qdCondition *p) {
|
|
conditions_.push_back(*p);
|
|
conditions_.back().set_owner(this);
|
|
|
|
return conditions_.size() - 1;
|
|
}
|
|
|
|
bool qdConditionalObject::update_condition(int num, const qdCondition &p) {
|
|
assert(num >= 0 && num < conditions_.size());
|
|
|
|
qdCondition &cond = conditions_[num];
|
|
cond = p;
|
|
cond.set_owner(this);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdConditionalObject::check_conditions() {
|
|
#ifndef _QUEST_EDITOR
|
|
qdCondition::clear_successful_clicks();
|
|
|
|
if (!conditions_.empty()) {
|
|
switch (conditions_mode()) {
|
|
case CONDITIONS_AND:
|
|
for (conditions_container_t::iterator it = conditions_.begin(); it != conditions_.end(); ++it) {
|
|
if (!it->is_in_group()) {
|
|
if (!it->check())
|
|
return false;
|
|
}
|
|
}
|
|
for (condition_groups_container_t::iterator it = condition_groups_.begin(); it != condition_groups_.end(); ++it) {
|
|
if (!check_group_conditions(*it))
|
|
return false;
|
|
}
|
|
return true;
|
|
case CONDITIONS_OR:
|
|
for (conditions_container_t::iterator it = conditions_.begin(); it != conditions_.end(); ++it) {
|
|
if (!it->is_in_group()) {
|
|
if (it->check())
|
|
return true;
|
|
}
|
|
}
|
|
for (condition_groups_container_t::iterator it = condition_groups_.begin(); it != condition_groups_.end(); ++it) {
|
|
if (check_group_conditions(*it))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
#endif // _QUEST_EDITOR
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdConditionalObject::remove_conditon(int idx) {
|
|
assert(idx >= 0 && idx < conditions_.size());
|
|
|
|
conditions_.erase(conditions_.begin() + idx);
|
|
|
|
for (condition_groups_container_t::iterator it = condition_groups_.begin(); it != condition_groups_.end(); ++it)
|
|
it->remove_condition(idx);
|
|
|
|
return true;
|
|
}
|
|
|
|
#ifdef _QUEST_EDITOR
|
|
void qdConditionalObject::remove_all_conditions() {
|
|
conditions_.clear();
|
|
}
|
|
void qdConditionalObject::remove_all_groups() {
|
|
condition_groups_.clear();
|
|
}
|
|
#endif
|
|
|
|
bool qdConditionalObject::load_conditions_script(const xml::tag *p) {
|
|
int count = 0;
|
|
int gr_count = 0;
|
|
|
|
for (xml::tag::subtag_iterator it = p->subtags_begin(); it != p->subtags_end(); ++it) {
|
|
switch (it->ID()) {
|
|
case QDSCR_CONDITION:
|
|
count++;
|
|
break;
|
|
case QDSCR_CONDITION_GROUP:
|
|
gr_count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (count) conditions_.resize(count);
|
|
conditions_container_t::iterator ict = conditions_.begin();
|
|
|
|
if (gr_count) condition_groups_.resize(gr_count);
|
|
condition_groups_container_t::iterator igt = condition_groups_.begin();
|
|
|
|
for (xml::tag::subtag_iterator it = p->subtags_begin(); it != p->subtags_end(); ++it) {
|
|
switch (it->ID()) {
|
|
case QDSCR_CONDITION:
|
|
if (const xml::tag * tp = it->search_subtag(QDSCR_TYPE)) {
|
|
qdCondition *cp = &*ict;
|
|
cp->set_type(qdCondition::ConditionType(xml::tag_buffer(*tp).get_int()));
|
|
cp->load_script(&*it);
|
|
cp->set_owner(this);
|
|
}
|
|
++ict;
|
|
break;
|
|
case QDSCR_CONDITION_GROUP:
|
|
if (const xml::tag * tp = it->search_subtag(QDSCR_TYPE))
|
|
igt->set_conditions_mode(qdConditionGroup::conditions_mode_t(xml::tag_buffer(*tp).get_int()));
|
|
igt->load_script(&*it);
|
|
++igt;
|
|
break;
|
|
case QDSCR_CONDITIONS_MODE:
|
|
set_conditions_mode(ConditionsMode((xml::tag_buffer(*it).get_int())));
|
|
break;
|
|
}
|
|
}
|
|
|
|
#ifndef _QUEST_EDITOR
|
|
for (int i = 0; i < conditions_.size(); i++) {
|
|
if (is_condition_in_group(i))
|
|
conditions_[i].add_group_reference();
|
|
}
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdConditionalObject::save_conditions_script(Common::WriteStream &fh, int indent) const {
|
|
if (conditions_.size()) {
|
|
for (auto &it : conditions_) {
|
|
it.save_script(fh, indent + 1);
|
|
}
|
|
|
|
for (int i = 0; i <= indent; i++) {
|
|
fh.writeString("\t");
|
|
}
|
|
|
|
fh.writeString(Common::String::format("<conditions_mode>%d</conditions_mode>\r\n", conditions_mode_));
|
|
}
|
|
|
|
for (auto &it : condition_groups_) {
|
|
it.save_script(fh, indent);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void qdConditionalObject::conditions_quant(float dt) {
|
|
for (auto &it : conditions_) {
|
|
it.quant(dt);
|
|
}
|
|
}
|
|
|
|
#ifdef _QUEST_EDITOR
|
|
bool qdConditionalObject::backup_object() {
|
|
backup_ = conditions_;
|
|
groups_backup_ = condition_groups_;
|
|
backup_mode_ = conditions_mode_;
|
|
return true;
|
|
}
|
|
|
|
bool qdConditionalObject::restore_object() {
|
|
conditions_ = backup_;
|
|
condition_groups_ = groups_backup_;
|
|
conditions_mode_ = backup_mode_;
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
bool qdConditionalObject::load_data(Common::SeekableReadStream &fh, int save_version) {
|
|
debugC(4, kDebugSave, " qdConditionalObject::load_data(): before %ld", fh.pos());
|
|
if (!qdNamedObject::load_data(fh, save_version))
|
|
return false;
|
|
|
|
for (auto &it : conditions_)
|
|
it.load_data(fh, save_version);
|
|
|
|
debugC(4, kDebugSave, " qdConditionalObject::load_data(): after %ld", fh.pos());
|
|
return true;
|
|
}
|
|
|
|
bool qdConditionalObject::save_data(Common::WriteStream &fh) const {
|
|
debugC(4, kDebugSave, " qdConditionalObject::save_data(): before %ld", fh.pos());
|
|
if (!qdNamedObject::save_data(fh)) {
|
|
return false;
|
|
}
|
|
|
|
for (auto &it : conditions_)
|
|
it.save_data(fh);
|
|
|
|
debugC(4, kDebugSave, " qdConditionalObject::save_data(): after %ld", fh.pos());
|
|
return true;
|
|
}
|
|
|
|
bool qdConditionalObject::check_group_conditions(const qdConditionGroup &gr) {
|
|
switch (gr.conditions_mode()) {
|
|
case qdConditionGroup::CONDITIONS_AND:
|
|
for (qdConditionGroup::conditions_iterator_t it = gr.conditions_begin(); it != gr.conditions_end(); ++it) {
|
|
if (!conditions_[*it].check())
|
|
return false;
|
|
}
|
|
return true;
|
|
case qdConditionGroup::CONDITIONS_OR:
|
|
for (qdConditionGroup::conditions_iterator_t it = gr.conditions_begin(); it != gr.conditions_end(); ++it) {
|
|
if (conditions_[*it].check())
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdConditionalObject::is_condition_in_group(int condition_idx) const {
|
|
for (condition_groups_container_t::const_iterator it = condition_groups_.begin(); it != condition_groups_.end(); ++it) {
|
|
if (std::find(it->conditions_begin(), it->conditions_end(), condition_idx) != it->conditions_end())
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int qdConditionalObject::add_condition_group(const qdConditionGroup *p) {
|
|
condition_groups_.push_back(*p);
|
|
return condition_groups_.size() - 1;
|
|
}
|
|
|
|
bool qdConditionalObject::update_condition_group(int num, const qdConditionGroup &p) {
|
|
assert(num >= 0 && num < condition_groups_.size());
|
|
|
|
qdConditionGroup &gr = condition_groups_[num];
|
|
gr = p;
|
|
|
|
#ifndef _QUEST_EDITOR
|
|
for (int i = 0; i < conditions_.size(); i++) {
|
|
if (is_condition_in_group(i))
|
|
conditions_[i].add_group_reference();
|
|
else
|
|
conditions_[i].remove_group_reference();
|
|
}
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
bool qdConditionalObject::remove_conditon_group(int idx) {
|
|
assert(idx >= 0 && idx < condition_groups_.size());
|
|
|
|
condition_groups_.erase(condition_groups_.begin() + idx);
|
|
|
|
#ifndef _QUEST_EDITOR
|
|
for (int i = 0; i < conditions_.size(); i++) {
|
|
if (is_condition_in_group(i))
|
|
conditions_[i].add_group_reference();
|
|
else
|
|
conditions_[i].remove_group_reference();
|
|
}
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
#ifdef _QUEST_EDITOR
|
|
bool qdConditionalObject::init_objects() {
|
|
bool result = true;
|
|
|
|
for (int i = 0; i < conditions_.size(); i++) {
|
|
if (!conditions_[i].init_objects())
|
|
result = false;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void qdConditionalObject::global_init() {
|
|
for (std::list<qdConditionalObject * >::const_iterator it = objects_list_.begin(); it != objects_list_.end(); ++it)
|
|
(*it)->init_objects();
|
|
}
|
|
#endif /* _QUEST_EDITOR */
|
|
|
|
bool qdConditionalObject::init() {
|
|
bool result = true;
|
|
|
|
for (int i = 0; i < conditions_.size(); i++) {
|
|
if (!conditions_[i].init())
|
|
result = false;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool qdConditionalObject::trigger_can_start() const {
|
|
if (const qdGameScene * p = static_cast<const qdGameScene * >(owner(QD_NAMED_OBJECT_SCENE)))
|
|
return p->is_active();
|
|
|
|
return true;
|
|
}
|
|
} // namespace QDEngine
|