]> git.localhorst.tv Git - l2e.git/commitdiff
lousy implementation of "array of identifiers" type
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 1 Dec 2012 09:51:05 +0000 (10:51 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 1 Dec 2012 09:51:05 +0000 (10:51 +0100)
see bug #34

src/loader/Interpreter.cpp
src/loader/ParsedSource.cpp
src/loader/ParsedSource.h
src/loader/Parser.cpp
src/map/Entity.h
src/map/MapState.cpp
test-data/maps.l2s

index 7dcb41e969c0de829f87ef56c67896e0c0dfc82a..e64110dbf7175801cbd2cde01aea701ce874d4d1 100644 (file)
@@ -127,10 +127,9 @@ void Interpreter::ReadLiteral(const Definition &dfn) {
 void Interpreter::ReadLiteral(int typeId, int id, char *object, const Literal &literal) {
        switch (literal.GetType()) {
                case Literal::ARRAY_VALUES:
-                       throw Error("named value arrays are not supported, sorry");
-                       break;
                case Literal::ARRAY_PROPS:
-                       throw Error("named property list arrays are not supported, sorry");
+               case Literal::ARRAY_IDENTS:
+                       throw Error("named arrays are not supported, sorry");
                        break;
                case Literal::BOOLEAN:
                        new (object) bool(literal.GetBoolean());
@@ -177,10 +176,9 @@ void *Interpreter::GetObject(int typeId, const Value &v) {
                        int typeId(0), id(0);
                        switch (v.GetLiteral().GetType()) {
                                case Literal::ARRAY_VALUES:
-                                       throw Error("cannot copy value arrays, sorry");
-                                       break;
                                case Literal::ARRAY_PROPS:
-                                       throw Error("cannot copy property list arrays, sorry");
+                               case Literal::ARRAY_IDENTS:
+                                       throw Error("cannot copy arrays, sorry");
                                        break;
                                case Literal::BOOLEAN:
                                        {
@@ -287,20 +285,35 @@ void Interpreter::ReadObject(int typeId, int id, char *object, const PropertyLis
                        char *dest(object + fd.Offset());
                        if (fd.IsAggregate()) {
                                int arraySize(i->second->GetLiteral().ArraySize());
-                               char *aggregate(alloc.Alloc(fieldType.Size() * arraySize));
-                               char *iter(aggregate);
+                               char *aggregate;
                                if (i->second->GetLiteral().GetType() == Literal::ARRAY_PROPS) {
+                                       aggregate = alloc.Alloc(fieldType.Size() * arraySize);
+                                       char *iter = aggregate;
                                        const vector<PropertyList *> &list(i->second->GetLiteral().GetPropertyLists());
                                        for (vector<PropertyList *>::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += fieldType.Size()) {
                                                fieldType.Construct(iter);
                                                ReadObject(fieldType.TypeId(), -1, iter, **j);
                                        }
-                               } else {
+                               } else if (i->second->GetLiteral().GetType() == Literal::ARRAY_VALUES) {
+                                       aggregate = alloc.Alloc(fieldType.Size() * arraySize);
+                                       char *iter = aggregate;
                                        const vector<Value *> &list(i->second->GetLiteral().GetValues());
                                        for (vector<Value *>::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += fieldType.Size()) {
                                                fieldType.Construct(iter);
                                                ReadLiteral(fieldType.TypeId(), -1, iter, (*j)->GetLiteral());
                                        }
+                               } else {
+                                       aggregate = alloc.Alloc(sizeof(char *) * arraySize);
+                                       char *iter = aggregate;
+                                       const vector<string> &list(i->second->GetLiteral().GetIdentifiers());
+                                       for (vector<string>::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += sizeof(void *)) {
+                                               if (source.IsDefined(*j)) {
+                                                       *reinterpret_cast<void **>(iter)
+                                                                       = GetObject(fd.TypeId(), *j);
+                                               } else {
+                                                       Postpone(typeId, id, fd.Offset() + (iter - aggregate), *j, fd.TypeId(), false);
+                                               }
+                                       }
                                }
                                if (fd.IsReferenced()) {
                                        std::memcpy(dest, &aggregate, sizeof(char *));
index 042dd69c7f6aeca25003268f40da54672d7068d9..90597475726663807fdc2beaa5b8f1d7fc627c98 100644 (file)
@@ -200,6 +200,17 @@ Literal::Literal(const string &typeName, const vector<PropertyList *> &pls)
 
 }
 
+Literal::Literal(const string &typeName, const vector<string> &ids)
+: props(0)
+, typeName(typeName)
+, identifiers(ids)
+, i1(0), i2(0)
+, i3(0), i4(0)
+, b(false)
+, type(ARRAY_IDENTS) {
+
+}
+
 Literal::Literal(bool b)
 : props(0)
 , typeName("Boolean")
@@ -324,6 +335,14 @@ const vector<PropertyList *> &Literal::GetPropertyLists() const {
        }
 }
 
+const vector<string> &Literal::GetIdentifiers() const {
+       if (type == ARRAY_IDENTS) {
+               return identifiers;
+       } else {
+               throw runtime_error("tried to access identifiers of non-array literal");
+       }
+}
+
 bool Literal::GetBoolean() const {
        if (type == BOOLEAN) {
                return b;
@@ -535,6 +554,9 @@ ostream &operator <<(ostream &out, const loader::Literal &l) {
                case loader::Literal::ARRAY_PROPS:
                        out << "array of property lists";
                        break;
+               case loader::Literal::ARRAY_IDENTS:
+                       out << "array of identifiers";
+                       break;
                case loader::Literal::BOOLEAN:
                        out << "boolean, " << (l.GetBoolean() ? "true" : "false");
                        break;
index b0578a78e548d017f7834d7cd810e889f0992089..c843de1889add9c37d22247ced22477533c37af1 100644 (file)
@@ -51,6 +51,7 @@ public:
        enum Type {
                ARRAY_VALUES,
                ARRAY_PROPS,
+               ARRAY_IDENTS,
                BOOLEAN,
                COLOR,
                NUMBER,
@@ -62,15 +63,27 @@ public:
        };
 
 public:
+       /// array of values
        explicit Literal(const std::vector<Value *> &);
+       /// array of objects
        Literal(const std::string &, const std::vector<PropertyList *> &);
+       /// array of identifiers
+       Literal(const std::string &, const std::vector<std::string> &);
+       /// boolean
        explicit Literal(bool);
+       /// color
        Literal(int r, int g, int b, int a = 255);
+       /// number
        explicit Literal(int number);
+       /// path string
        Literal(const std::string &dir, const std::string &path);
+       /// string
        Literal(const std::string &);
+       /// vector
        Literal(int x, int y);
+       /// object
        Literal(const std::string &typeName, PropertyList *properties);
+       /// script
        explicit Literal(const std::vector<ScriptToken *> &);
        ~Literal();
 private:
@@ -79,12 +92,14 @@ private:
 
 public:
        Type GetType() const { return type; }
-       bool IsArray() const { return GetType() == ARRAY_VALUES || GetType() == ARRAY_PROPS; }
+       bool IsArray() const { return GetType() == ARRAY_VALUES || GetType() == ARRAY_PROPS || GetType() == ARRAY_IDENTS; }
        bool IsObject() const { return GetType() == OBJECT; }
-       int ArraySize() const { return GetType() == ARRAY_VALUES ? GetValues().size() : GetPropertyLists().size(); }
+       int ArraySize() const { return GetType() == ARRAY_VALUES ? GetValues().size()
+                       : (GetType() == ARRAY_PROPS ? GetPropertyLists().size() : GetIdentifiers().size()); }
 
        const std::vector<Value *> &GetValues() const;
        const std::vector<PropertyList *> &GetPropertyLists() const;
+       const std::vector<std::string> &GetIdentifiers() const;
        bool GetBoolean() const;
        int GetRed() const;
        int GetGreen() const;
@@ -103,6 +118,7 @@ private:
        std::string typeName, str;
        std::vector<Value *> values;
        std::vector<PropertyList *> propertyLists;
+       std::vector<std::string> identifiers;
        std::vector<ScriptToken *> script;
        int i1, i2, i3, i4;
        bool b;
index cba4f316f8d5251d1f878d7b2d612ce0f903655e..3f5f3446955ab8d78005912ad1d31df432c658e8 100644 (file)
@@ -259,17 +259,33 @@ Literal *Parser::ParseArray() {
        Token probe(GetToken());
 
        if (probe.type == Token::TYPE_NAME) {
-               vector<PropertyList *> values;
-               while (t.type != Token::BRACKET_CLOSE) {
-                       PropertyList *value(ParsePropertyList());
-                       values.push_back(value);
+               t = GetToken();
+               tok.Putback(t);
+               if (t.type == Token::ANGLE_BRACKET_OPEN) {
+                       vector<PropertyList *> values;
+                       while (t.type != Token::BRACKET_CLOSE) {
+                               PropertyList *value(ParsePropertyList());
+                               values.push_back(value);
 
-                       t = GetToken();
-                       if (t.type != Token::BRACKET_CLOSE && t.type != Token::COMMA) {
-                               throw Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(t.type) + ", expected , or ]");
+                               t = GetToken();
+                               if (t.type != Token::BRACKET_CLOSE && t.type != Token::COMMA) {
+                                       throw Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(t.type) + ", expected , or ]");
+                               }
+                       }
+                       return new Literal(probe.str, values);
+               } else {
+                       vector<string> values;
+                       while (t.type != Token::BRACKET_CLOSE) {
+                               string value(ParseIdentifier());
+                               values.push_back(value);
+
+                               t = GetToken();
+                               if (t.type != Token::BRACKET_CLOSE && t.type != Token::COMMA) {
+                                       throw Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(t.type) + ", expected , or ]");
+                               }
                        }
+                       return new Literal(probe.str, values);
                }
-               return new Literal(probe.str, values);
        } else {
                tok.Putback(probe);
 
index a6c4201763df75c161c3a88604398230efaf663a..d1746c71a3cd73ff77dc37fb03de899796bdcf6f 100644 (file)
@@ -110,9 +110,9 @@ public:
 
        /// Add monsters. This will cause the entity to be Hostile() and result in a
        /// battle scene with given monsters when touched.
-       void SetMonsters(battle::Monster *m, int num) { monsters = m; numMonsters = num; }
-       battle::Monster *MonstersBegin() { return monsters; }
-       battle::Monster *MonstersEnd() { return monsters + numMonsters; }
+       void SetMonsters(battle::Monster **m, int num) { monsters = m; numMonsters = num; }
+       battle::Monster **MonstersBegin() { return monsters; }
+       battle::Monster **MonstersEnd() { return monsters + numMonsters; }
 
        /// Get an entity that should follow in this one's steps or 0 if none.
        Entity *Follower() { return follower; }
@@ -143,7 +143,7 @@ private:
        const graphics::Animation *animation;
        const graphics::Sprite *sprite;
        battle::PartyLayout *partyLayout;
-       battle::Monster *monsters;
+       battle::Monster **monsters;
        int numMonsters;
        graphics::AnimationRunner runner;
        geometry::Vector<int> spriteOffset;
index 7b0905d37654fc50819a2b53f9218ce878ea663b..d678dab965d573c7722a963a9cc5936ac57af5c6 100644 (file)
@@ -296,8 +296,8 @@ bool MapState::CheckMonster() {
                                                battleState->AddHero(*game->state->party[i]);
                                        }
                                }
-                               for (battle::Monster *monster((*e)->MonstersBegin()); monster != (*e)->MonstersEnd(); ++monster) {
-                                       battleState->AddMonster(*monster);
+                               for (battle::Monster **monster((*e)->MonstersBegin()); monster != (*e)->MonstersEnd(); ++monster) {
+                                       battleState->AddMonster(**monster);
                                }
 
                                ColorFade *fadeIn(new ColorFade(this, 0, 500, true));
index e5ffbcde046293a5faffa033d70aca48ce7e0e8e..b70aa3c8cec28a0c88df3d2579ec1c02c706ebf5 100644 (file)
@@ -185,8 +185,11 @@ export Map map1 {
                                repeat: true
                        },
                        position: <2, 1>,
-                       partyLayout: monstersLayout
-                       // TODO: monsters
+                       partyLayout: monstersLayout,
+                       monsters: [ Monster
+                               lizard,
+                               lizard
+                       ]
                },
                {
                        sprite: Sprite {