mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 13:06:59 -04:00
Added new_card function;
Added parameter to ScriptValue::next to recieve the key of the item. Finished Add Multiple Cards behaviour. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1147 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -479,9 +479,10 @@ void Context::makeObject(size_t n) {
|
||||
for (size_t i = 0 ; i < n ; ++i) {
|
||||
const ScriptValueP& key = stack[begin + 2 * i];
|
||||
const ScriptValueP& val = stack[begin + 2 * i + 1];
|
||||
ret->value.push_back(val);
|
||||
if (key != script_nil) { // valid key
|
||||
ret->key_value[key->toString()] = val;
|
||||
} else {
|
||||
ret->value.push_back(val);
|
||||
}
|
||||
}
|
||||
stack.resize(begin);
|
||||
|
||||
@@ -28,7 +28,7 @@ class DependencyDummy : public ScriptIterator {
|
||||
public:
|
||||
virtual ScriptType type() const { return SCRIPT_DUMMY; }
|
||||
virtual String typeName() const { return _("dummy"); }
|
||||
virtual ScriptValueP next() { return ScriptValueP(); }
|
||||
virtual ScriptValueP next(ScriptValueP*) { return ScriptValueP(); }
|
||||
virtual ScriptValueP dependencyName(const ScriptValue&, const Dependency&) const { return dependency_dummy; }
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
//+----------------------------------------------------------------------------+
|
||||
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||
//| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" |
|
||||
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||
//+----------------------------------------------------------------------------+
|
||||
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <script/functions/functions.hpp>
|
||||
#include <script/functions/util.hpp>
|
||||
#include <data/field.hpp>
|
||||
#include <data/field/text.hpp>
|
||||
#include <data/field/choice.hpp>
|
||||
#include <data/field/package_choice.hpp>
|
||||
#include <data/field/color.hpp>
|
||||
#include <data/game.hpp>
|
||||
#include <data/card.hpp>
|
||||
#include <util/error.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : new_card
|
||||
|
||||
SCRIPT_FUNCTION(new_card) {
|
||||
SCRIPT_PARAM(GameP, game);
|
||||
CardP new_card = new_intrusive1<Card>(*game);
|
||||
// set field values
|
||||
SCRIPT_PARAM(ScriptValueP, input);
|
||||
ScriptValueP it = input->makeIterator(input);
|
||||
ScriptValueP key;
|
||||
while (ScriptValueP v = it->next(&key)) {
|
||||
assert(key);
|
||||
String name = key->toString();
|
||||
// find value to update
|
||||
IndexMap<FieldP,ValueP>::const_iterator value_it = new_card->data.find(name);
|
||||
if (value_it == new_card->data.end()) {
|
||||
throw ScriptError(format_string(_("Card doesn't have a field named '%s'"),name));
|
||||
}
|
||||
Value* value = value_it->get();
|
||||
// set the value
|
||||
if (TextValue* tvalue = dynamic_cast<TextValue*>(value)) {
|
||||
tvalue->value = v->toString();
|
||||
} else if (ChoiceValue* cvalue = dynamic_cast<ChoiceValue*>(value)) {
|
||||
cvalue->value = v->toString();
|
||||
} else if (PackageChoiceValue* pvalue = dynamic_cast<PackageChoiceValue*>(value)) {
|
||||
pvalue->package_name = v->toString();
|
||||
} else if (ColorValue* cvalue = dynamic_cast<ColorValue*>(value)) {
|
||||
cvalue->value = (AColor)*v;
|
||||
} else {
|
||||
throw ScriptError(format_string(_("Can not set value '%s', it is not of the right type"),name));
|
||||
}
|
||||
}
|
||||
SCRIPT_RETURN(new_card);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Init
|
||||
|
||||
void init_script_construction_functions(Context& ctx) {
|
||||
ctx.setVariable(_("new card"), script_new_card);
|
||||
}
|
||||
@@ -26,6 +26,7 @@ void init_script_image_functions(Context& ctx);
|
||||
void init_script_editor_functions(Context& ctx);
|
||||
void init_script_export_functions(Context& ctx);
|
||||
void init_script_english_functions(Context& ctx);
|
||||
void init_script_construction_functions(Context& ctx);
|
||||
|
||||
/// Initialize all built in functions for a context
|
||||
inline void init_script_functions(Context& ctx) {
|
||||
@@ -35,6 +36,7 @@ inline void init_script_functions(Context& ctx) {
|
||||
init_script_editor_functions(ctx);
|
||||
init_script_export_functions(ctx);
|
||||
init_script_english_functions(ctx);
|
||||
init_script_construction_functions(ctx);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
|
||||
@@ -92,7 +92,7 @@ struct ScriptIterator : public ScriptValue {
|
||||
virtual CompareWhat compareAs(String&, void const*&) const; // { return COMPARE_NO; }
|
||||
|
||||
/// Return the next item for this iterator, or ScriptValueP() if there is no such item
|
||||
virtual ScriptValueP next() = 0;
|
||||
virtual ScriptValueP next(ScriptValueP* key_out = nullptr) = 0;
|
||||
};
|
||||
|
||||
// make an iterator over a range
|
||||
@@ -100,6 +100,8 @@ ScriptValueP rangeIterator(int start, int end);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Collections
|
||||
|
||||
ScriptValueP to_script(int);
|
||||
|
||||
class ScriptCollectionBase : public ScriptValue {
|
||||
public:
|
||||
virtual ScriptType type() const { return SCRIPT_COLLECTION; }
|
||||
@@ -111,8 +113,9 @@ template <typename Collection>
|
||||
class ScriptCollectionIterator : public ScriptIterator {
|
||||
public:
|
||||
ScriptCollectionIterator(const Collection* col) : pos(0), col(col) {}
|
||||
virtual ScriptValueP next() {
|
||||
virtual ScriptValueP next(ScriptValueP* key_out) {
|
||||
if (pos < col->size()) {
|
||||
if (key_out) *key_out = to_script((int)pos);
|
||||
return to_script(col->at(pos++));
|
||||
} else {
|
||||
return ScriptValueP();
|
||||
@@ -213,7 +216,7 @@ class ScriptCustomCollection : public ScriptCollectionBase {
|
||||
return COMPARE_AS_POINTER;
|
||||
}
|
||||
|
||||
/// The collection as a list (contains all values)
|
||||
/// The collection as a list (contains only the values that don't have a key)
|
||||
vector<ScriptValueP> value;
|
||||
/// The collection as a map (contains only the values that have a key)
|
||||
map<String,ScriptValueP> key_value;
|
||||
|
||||
+22
-13
@@ -25,7 +25,7 @@ ScriptValue::operator bool() const { throw Script
|
||||
ScriptValue::operator double() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("double" ))); }
|
||||
ScriptValue::operator AColor() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("color" ))); }
|
||||
ScriptValueP ScriptValue::eval(Context&) const { return delayError(_ERROR_2_("can't convert", typeName(), _TYPE_("function"))); }
|
||||
ScriptValueP ScriptValue::next() { throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator")); }
|
||||
ScriptValueP ScriptValue::next(ScriptValueP* key_out) { throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator")); }
|
||||
ScriptValueP ScriptValue::makeIterator(const ScriptValueP&) const { return delayError(_ERROR_2_("can't convert", typeName(), _TYPE_("collection"))); }
|
||||
int ScriptValue::itemCount() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("collection"))); }
|
||||
GeneratedImageP ScriptValue::toImage(const ScriptValueP&) const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("image" ))); }
|
||||
@@ -129,8 +129,9 @@ class ScriptRangeIterator : public ScriptIterator {
|
||||
// Construct a range iterator with the given bounds (inclusive)
|
||||
ScriptRangeIterator(int start, int end)
|
||||
: pos(start), end(end) {}
|
||||
virtual ScriptValueP next() {
|
||||
virtual ScriptValueP next(ScriptValueP* key_out) {
|
||||
if (pos <= end) {
|
||||
if (key_out) *key_out = to_script(pos);
|
||||
return to_script(pos++);
|
||||
} else {
|
||||
return ScriptValueP();
|
||||
@@ -359,6 +360,7 @@ String ScriptCollectionBase::toCode() const {
|
||||
while (ScriptValueP v = it->next()) {
|
||||
if (!first) ret += _(",");
|
||||
first = false;
|
||||
// todo: include keys
|
||||
ret += v->toCode();
|
||||
}
|
||||
ret += _("]");
|
||||
@@ -370,19 +372,23 @@ String ScriptCollectionBase::toCode() const {
|
||||
// Iterator over a custom collection
|
||||
class ScriptCustomCollectionIterator : public ScriptIterator {
|
||||
public:
|
||||
ScriptCustomCollectionIterator(const vector<ScriptValueP>* col, ScriptValueP colP)
|
||||
: pos(0), col(col), colP(colP) {}
|
||||
virtual ScriptValueP next() {
|
||||
if (pos < col->size()) {
|
||||
return col->at(pos++);
|
||||
ScriptCustomCollectionIterator(ScriptCustomCollectionP col)
|
||||
: col(col), pos(0), it(col->key_value.begin()) {}
|
||||
virtual ScriptValueP next(ScriptValueP* key_out) {
|
||||
if (pos < col->value.size()) {
|
||||
if (key_out) *key_out = to_script((int)pos);
|
||||
return col->value.at(pos++);
|
||||
} else if (it != col->key_value.end()) {
|
||||
if (key_out) *key_out = to_script(it->first);
|
||||
return (it++)->second;
|
||||
} else {
|
||||
return ScriptValueP();
|
||||
}
|
||||
}
|
||||
private:
|
||||
ScriptCustomCollectionP col;
|
||||
size_t pos;
|
||||
const vector<ScriptValueP>* col;
|
||||
ScriptValueP colP; // for ownership of the collection
|
||||
map<String,ScriptValueP>::const_iterator it;
|
||||
};
|
||||
|
||||
ScriptValueP ScriptCustomCollection::getMember(const String& name) const {
|
||||
@@ -401,7 +407,9 @@ ScriptValueP ScriptCustomCollection::getIndex(int index) const {
|
||||
}
|
||||
}
|
||||
ScriptValueP ScriptCustomCollection::makeIterator(const ScriptValueP& thisP) const {
|
||||
return new_intrusive2<ScriptCustomCollectionIterator>(&value, thisP);
|
||||
return new_intrusive1<ScriptCustomCollectionIterator>(
|
||||
static_pointer_cast<ScriptCustomCollection>(thisP)
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Concat collection
|
||||
@@ -411,13 +419,14 @@ class ScriptConcatCollectionIterator : public ScriptIterator {
|
||||
public:
|
||||
ScriptConcatCollectionIterator(const ScriptValueP& itA, const ScriptValueP& itB)
|
||||
: itA(itA), itB(itB) {}
|
||||
virtual ScriptValueP next() {
|
||||
virtual ScriptValueP next(ScriptValueP* key_out) {
|
||||
if (itA) {
|
||||
ScriptValueP v = itA->next();
|
||||
ScriptValueP v = itA->next(key_out);
|
||||
if (v) return v;
|
||||
else itA = ScriptValueP();
|
||||
}
|
||||
return itB->next();
|
||||
// TODO: somehow fix up the keys
|
||||
return itB->next(key_out);
|
||||
}
|
||||
private:
|
||||
ScriptValueP itA, itB;
|
||||
|
||||
@@ -105,7 +105,8 @@ class ScriptValue : public IntrusivePtrBaseWithDelete {
|
||||
/** thisP can be used to prevent destruction of the collection */
|
||||
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const;
|
||||
/// Return the next item for this iterator, or ScriptValueP() if there is no such item
|
||||
virtual ScriptValueP next();
|
||||
/** If key_out != 0, then it will recieve the key of the item */
|
||||
virtual ScriptValueP next(ScriptValueP* key_out = nullptr);
|
||||
/// Return the number of items in this value (assuming it is a collection)
|
||||
virtual int itemCount() const;
|
||||
/// Get a member at the given index
|
||||
|
||||
Reference in New Issue
Block a user