Example #1
0
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="plDoneMask">   Mask of game which has been done</param>
        public frmLoadPuzzle(long[] plDoneMask)
        {
            List <PuzzleItem> listPuzzleItem;
            PuzzleItem        puzzleItem;
            int  iCount;
            bool bDone;

            InitializeComponent();
            m_plDoneMask = plDoneMask;
            m_pgnParser  = new PgnParser(false);
            if (m_listPGNGame == null)
            {
                BuildPuzzleList();
            }
            listPuzzleItem = new List <PuzzleItem>(m_listPGNGame.Count);
            iCount         = 0;
            foreach (PgnGame pgnGame in m_listPGNGame)
            {
                if (plDoneMask == null)
                {
                    bDone = false;
                }
                else
                {
                    bDone = (plDoneMask[iCount / 64] & (1L << (iCount & 63))) != 0;
                }
                iCount++;
                puzzleItem = new PuzzleItem(iCount, pgnGame.Event, bDone);
                listPuzzleItem.Add(puzzleItem);
            }
            listViewPuzzle.ItemsSource   = listPuzzleItem;
            listViewPuzzle.SelectedIndex = 0;
        }
Example #2
0
        // General outline of puzzle generation
        protected virtual bool spawnFilteredOutput(string outputName)
        {
            if (!Database.Instance.itemExists(outputName))
            {
                if (_verbose)
                {
                    Debug.Log("Failed to generate puzzle, output does not exist in database " + outputName);
                }
                return(false);
            }

            DBItem dbitem = Database.Instance.getItem(outputName);

            if (dbitem.Spawned)
            {
                if (_verbose)
                {
                    Debug.Log("Failed to generate puzzle: " + outputName + " already spawned");
                }
                return(false);
            }

            PuzzleItem output = dbitem.spawnItem();

            _spawnedItems.Add(outputName);
            output = applyPropertiesToSpawnedItem(_desiredOutputProperties, output);
            // Give the output a unique id if it doesn't already have one
            if (!output.propertyExists("spawnIndex"))
            {
                output.setProperty("spawnIndex", dbitem.NextSpawnIndex);
            }
            _spawnedOutput = output;
            return(true);
        }
Example #3
0
    private void TestPuzzle()
    {
        string answer1 = "boega";
        string answer2 = "fut";

        PuzzleItem puz1 = new PuzzleItem("Jeffrey", 10, "OeGa", "bOeGa");
        PuzzleItem puz2 = new PuzzleItem("Henk", 12, "Me", "faT");

        Debug.Log("R: " + puz1.GetRiddle() + "\n    A: " + puz1.GetAnswer());
        if (puz1.IsSolved(answer1))
        {
            Debug.Log("Is solved puz1");
        }
        else
        {
            Debug.Log("Answer 1: <" + answer1 + "> Was incorrect");
        }

        Debug.Log("R: " + puz2.GetRiddle() + "\n    A: " + puz2.GetAnswer());
        if (puz2.IsSolved(answer2))
        {
            Debug.Log("Is solved puz2");
        }
        else
        {
            Debug.Log("Answer 2: <" + answer2 + "> Was incorrect");
        }
    }
Example #4
0
        // The function that is the official entry point to generating a puzzle with this building block
        public virtual PuzzleOutput generatePuzzle(string outputName, Dictionary <string, object> desiredOutputProperties)
        {
            _itemsToSpawn            = new List <PuzzleItem>();
            _relationshipsToSpawn    = new List <IRelationship>();
            _desiredOutputProperties = desiredOutputProperties;
            _spawnedOutput           = null;
            if (_verbose)
            {
                Debug.Log("Generating puzzle for  " + outputName);
            }
            if (!spawnFilteredOutput(outputName))
            {
                return(null);
            }
            if (!spawnFilteredInputs(outputName))
            {
                return(null);
            }
            // In case of success, time to create a puzzle output
            PuzzleOutput result = new PuzzleOutput();

            result.Items         = _itemsToSpawn;
            result.Relationships = _relationshipsToSpawn;
            return(result);
        }
Example #5
0
    protected SpawnedPuzzleItem spawnItem(PuzzleItem item)
    {
        _itemNames.Add(item.Name);
        GameObject        puzzleItemObj = GameObject.Instantiate(PlayState.instance.puzzleItemPrefab) as GameObject;
        SpawnedPuzzleItem spawnedItem   = puzzleItemObj.GetComponent <SpawnedPuzzleItem>();

        // Give the spawned item all the appropriate properties.
        foreach (string propertyName in item.getPropertyNames())
        {
            spawnedItem.setProperty(propertyName, item.getProperty(propertyName));
        }
        if (getRequest(spawnedItem.itemName) != null)
        {
            spawnedItem.initRequest(getRequest(spawnedItem.itemName));
        }

        // Figure out where to spawn the item
        if (item.propertyExists("spawnArea"))
        {
            string spawnAreaName = item.getProperty("spawnArea") as string;
            addArea(spawnAreaName);
            _areaRooms[spawnAreaName].addPiece(spawnedItem);
        }
        return(spawnedItem);
    }
Example #6
0
        public PuzzleItem spawnItem()
        {
            _numSpawned++;

            PuzzleItem    itemToReturn = new PuzzleItem(_className);
            List <string> mutables;

            if (_properties.ContainsKey("mutables"))
            {
                mutables = _properties["mutables"] as List <string>;
            }
            else
            {
                mutables = new List <string>();
            }


            // Copy properties from the dbitem to the output item
            foreach (string propertyName in _properties.Keys)
            {
                if (!mutables.Contains(propertyName))
                {
                    itemToReturn.setProperty(propertyName, _properties[propertyName]);
                }
            }

            return(itemToReturn);
        }
Example #7
0
        private void okBtn_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(this.titleTextBox.Text))
            {
                MessageWindow msgWnd = new MessageWindow();
                msgWnd.ShowMessage(SoonLearning.BlockPuzzle.Properties.Resources.TitleEmpty, MessageBoxButton.OK, null);
                this.titleTextBox.SelectAll();
                this.titleTextBox.Focus();
                return;
            }

            if (string.IsNullOrEmpty(this.imageFile))
            {
                MessageWindow msgWnd = new MessageWindow();
                msgWnd.ShowMessage(SoonLearning.BlockPuzzle.Properties.Resources.SelectImageForNewPuzzle, MessageBoxButton.OK, null);
                return;
            }

            item = PuzzleItem.CreatePuzzle(this.titleTextBox.Text, this.imageFile, "SoonLearning");

            ControlMgr.Instance.DataMgr.Add(item);

            //     File.Copy(this.imageFile, System.IO.Path.Combine(dataFolder, item.ImageFile));

            ControlMgr.Instance.PuzzleStartupPage.ShowPuzzleList();
        }
Example #8
0
    protected SpawnedPuzzleItem spawnLockedDoor()
    {
        DBItem     lockDB   = Database.Instance.getItem("lock");
        PuzzleItem lockItem = lockDB.spawnItem();

        return(spawnItem(lockItem));
    }
Example #9
0
 public CombineRelationship(string ingredient1Name, int ing1Index, string ingredient2Name, int ing2Index, PuzzleItem resultItem)
 {
     _ingredient1Name  = ingredient1Name;
     _ingredient1Index = ing1Index;
     _ingredient2Name  = ingredient2Name;
     _ingredient2Index = ing2Index;
     _resultItem       = resultItem;
 }
Example #10
0
 public CombineRelationship(string ingredient1Name, int ing1Index, string ingredient2Name, int ing2Index, PuzzleItem resultItem)
 {
     _ingredient1Name = ingredient1Name;
     _ingredient1Index = ing1Index;
     _ingredient2Name = ingredient2Name;
     _ingredient2Index = ing2Index;
     _resultItem = resultItem;
 }
Example #11
0
    public void AddItem(PuzzleItem item)
    {
        ItemFront itemFront = Instantiate(itemPrefab) as ItemFront;

        itemFront.transform.parent = transform;
        itemFront.gameObject.name  = "Item " + item.GetType().Name.Replace("Puzzle", "");
        itemFront.Set(this, item);
        items.Add(itemFront);
    }
Example #12
0
    public void Set(PuzzleFront puzzle, PuzzleItem item)
    {
        m_Puzzle = puzzle;
        m_Item   = item;

        transform.parent   = puzzle.transform;
        transform.position = puzzle.GetNode(item.defaultNode).transform.position;
        SetItem(item);
    }
 public ItemRequestRelationship(string requesterName, int requesterIndex, string requestedName, int requestedIndex, PuzzleItem rewardItem, string propertyName, object propertyVal)
 {
     _requesterName = requesterName;
     _requesterIndex = requesterIndex;
     _requestedName = requestedName;
     _requestedIndex = requestedIndex;
     _rewardItem = rewardItem;
     _requestedPropertyName = propertyName;
     _requestedPropertyVal = propertyVal;
 }
Example #14
0
    public PuzzleNode GetItemNode(PuzzleState state, PuzzleItem item)
    {
        int index = items.IndexOf(item);

        if (index < 0)
        {
            return(null);
        }
        return(nodes[state.itemValues[index]]);
    }
 public ItemRequestRelationship(string requesterName, int requesterIndex, string requestedName, int requestedIndex, PuzzleItem rewardItem, string propertyName, object propertyVal)
 {
     _requesterName         = requesterName;
     _requesterIndex        = requesterIndex;
     _requestedName         = requestedName;
     _requestedIndex        = requestedIndex;
     _rewardItem            = rewardItem;
     _requestedPropertyName = propertyName;
     _requestedPropertyVal  = propertyVal;
 }
Example #16
0
 public void AddToInventory(PuzzleItem item)
 {
     inventory.Add(item);
     if (inventory.Count < inventorySlots.Length)
     {
         inventorySlots[inventory.Count - 1].sprite = item.puzzleItemImage;
     }
     item.gameObject.SetActive(false);
     InspectInventory(inventory.Count - 1);
 }
Example #17
0
 public ItemFront GetItem(PuzzleItem item)
 {
     foreach (ItemFront itemFront in items)
     {
         if (itemFront.item == item)
         {
             return(itemFront);
         }
     }
     return(null);
 }
Example #18
0
    public void SetItemNode(PuzzleState state, PuzzleItem item, PuzzleNode node)
    {
        int itemIndex = items.IndexOf(item);
        int nodeIndex = nodes.IndexOf(node);

        if (itemIndex < 0 || nodeIndex < 0)
        {
            return;
        }
        state.itemValues[itemIndex] = nodeIndex;
    }
        private ThumbnailItem win_DataItemLoadedEvent(string file)
        {
            PuzzleItem pi = PuzzleData.LoadPuzzleItem(file);

            if (pi.Type != PuzzleSetting.Instance.Type)
            {
                return(null);
            }
            pi.ImageFile = file;
            ControlMgr.Instance.DataMgr.Add(pi);
            return(pi);
        }
Example #20
0
 public void RemoveItem(PuzzleItem item)
 {
     foreach (ItemFront itemFront in items)
     {
         if (itemFront.item == item)
         {
             Destroy(itemFront.gameObject);
             items.Remove(itemFront);
             break;
         }
     }
 }
Example #21
0
    private void SetItem(PuzzleItem puzzleItem)
    {
        string name = puzzleItem.GetType().Name.Replace("Puzzle", "");

        foreach (var item in items)
        {
            if (item.name == name)
            {
                staticSprite.sprite = item.image;
            }
        }
    }
Example #22
0
    private void ShowPuzzleItems()
    {
        int start = pageNum * itemsPerPage;

        for (int i = 0; i < itemsPerPage; i++)
        {
            if (puzzles.Count <= start + i)
            {
                return;
            }
            PuzzleItem item = items[i].GetComponent <PuzzleItem>();
            Debug.Log("sssss");

            item.Init(puzzles[start + i]);
        }
    }
Example #23
0
    protected SpawnedPuzzleItem spawnItem(PuzzleItem item)
    {
        GameObject        newObj      = GameObject.Instantiate(PlayState.instance.puzzleItemPrefab) as GameObject;
        SpawnedPuzzleItem spawnedItem = newObj.GetComponent <SpawnedPuzzleItem>();

        // Give the spawned item all the appropriate properties.
        foreach (string propertyName in item.getPropertyNames())
        {
            spawnedItem.setProperty(propertyName, item.getProperty(propertyName));
        }

        if (_game.getRequest(spawnedItem.itemName) != null)
        {
            spawnedItem.initRequest(_game.getRequest(spawnedItem.itemName));
        }

        return(spawnedItem);
    }
Example #24
0
        // A useful function for applying our desired properties to a spawned item
        // useful primarily because it allows leeway for doing things like inserting items into containers
        // via the contains property
        protected virtual PuzzleItem applyPropertiesToSpawnedItem(Dictionary <string, object> desiredProperties, PuzzleItem item)
        {
            foreach (string propertyName in desiredProperties.Keys)
            {
                if (propertyName == "contains")
                {
                    List <PuzzleItem> itemsInside   = new List <PuzzleItem>();
                    List <string>     itemsToInsert = desiredProperties["contains"] as List <string>;
                    foreach (string itemToInsertName in itemsToInsert)
                    {
                        if (!Database.Instance.itemExists(itemToInsertName))
                        {
                            if (_verbose)
                            {
                                Debug.Log("Puzzle failed to generate output, internal item " + itemToInsertName + " does not exist");
                            }
                            return(null);
                        }
                        if (Database.Instance.getItem(itemToInsertName).Spawned)
                        {
                            if (_verbose)
                            {
                                Debug.Log("Puzzle failed to generate output. Internal item " + itemToInsertName + " already spawned");
                            }
                            return(null);
                        }
                        PuzzleItem itemToInsert = Database.Instance.getItem(itemToInsertName).spawnItem();
                        applyPropertiesToSpawnedItem(desiredProperties["innerItemProps"] as Dictionary <string, object>, itemToInsert);
                        itemsInside.Add(itemToInsert);
                        _spawnedItems.Add(itemToInsertName);
                    }
                    item.setProperty("contains", itemsInside);
                }
                else
                {
                    item.setProperty(propertyName, desiredProperties[propertyName]);
                }
            }

            return(item);
        }
    public void Activate(List <GameObject> puzzlePrefabs, List <string> _puzzleTexts, string tutorialText, PuzzleItem _pi)
    {
        if (active)
        {
            return;
        }
        active = true;
        //puzzleIndex = 0;
        gameObject.transform.GetChild(0).position = new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y, transform.position.z);
        transform.GetChild(0).gameObject.SetActive(true);
        GameManager.instance.puzzleActive = true;
        if (!tutorialSeen && tutorialText != "")
        {
            StartCoroutine(FadeAndSetActive(textField.GetComponent <SpriteRenderer>(), textField, 1f, .3f));
            textField.GetComponentInChildren <TextMeshProUGUI>().text = tutorialText.Replace("\\n", "\n");

            tutorialSeen = true;
            textActive   = true;
            foreach (GameObject gi in deactivateOnText)
            {
                gi.SetActive(false);
            }
        }
        else
        {
            textField.gameObject.SetActive(false);
            foreach (GameObject gi in deactivateOnText)
            {
                gi.SetActive(true);
            }
            puzzle = Instantiate(puzzlePrefabs[puzzleIndex], new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y, transform.position.z), Quaternion.identity, transform.GetChild(0));
        }

        activePuzzlePrefabs = puzzlePrefabs;
        puzzleTexts         = _puzzleTexts;
        pi = _pi;
        counterText.text = puzzleIndex.ToString() + "/" + activePuzzlePrefabs.Count.ToString();
    }
Example #26
0
    protected SpawnedPuzzleItem spawnItem(PuzzleItem item)
    {
        _itemNames.Add(item.Name);
        GameObject puzzleItemObj = GameObject.Instantiate(PlayState.instance.puzzleItemPrefab) as GameObject;
        SpawnedPuzzleItem spawnedItem = puzzleItemObj.GetComponent<SpawnedPuzzleItem>();

        // Give the spawned item all the appropriate properties.
        foreach (string propertyName in item.getPropertyNames()) {
            spawnedItem.setProperty(propertyName, item.getProperty(propertyName));
        }
        if (getRequest(spawnedItem.itemName) != null)
            spawnedItem.initRequest(getRequest(spawnedItem.itemName));

        // Figure out where to spawn the item
        if (item.propertyExists("spawnArea")) {
            string spawnAreaName = item.getProperty("spawnArea") as string;
            addArea(spawnAreaName);
            _areaRooms[spawnAreaName].addPiece(spawnedItem);
        }
        return spawnedItem;
    }
Example #27
0
    void ContainerWindow(int id)
    {
        Rect position = GetInnerWindowRect(containerWindowRect);

        position.width  = kLargeButtonSize;
        position.height = kLargeButtonSize;

        PuzzleNode node = selected as PuzzleNode;

        ElementData[] elements = node != null ?
                                 puzzleFrontPrefab.nodePrefab.elements :
                                 puzzleFrontPrefab.edgePrefab.elements;

        // Container options
        for (int i = 0; i < elements.Length; i++)
        {
            ElementData elementData   = elements[i];
            bool        chosenElement = (selected.element != null && selected.element.GetType() == elementData.type);

            if (i % 2 == 0)
            {
                position.x = kBorder + kSpacing;
            }
            else
            {
                position.x += kLargeButtonSize + kSpacing;
            }

            if (ElementButton(position, elementData, chosenElement))
            {
                if (!chosenElement)
                {
                    if (selected.element != null)
                    {
                        puzzle.RemoveElement(selected.element);
                    }
                    PuzzleElement element = (PuzzleElement)Activator.CreateInstance(elementData.type);
                    selected.element = element;
                    puzzle.AddElement(element);
                }
                else
                {
                    puzzle.RemoveElement(selected.element);
                }
            }

            if (i % 2 == 1 || i == elements.Length - 1)
            {
                position.y += kLargeButtonSize + kSpacing;
            }
        }

        position.y += 10;

        if (selected.element != null)
        {
            var boolElement = selected.element as PuzzleBoolElement;
            if (boolElement != null)
            {
                position.x      = kBorder + kSpacing;
                position.width  = GetInnerWindowRect(containerWindowRect).width;
                position.height = 24;
                Rect pos = new Rect(position.x, position.y, position.width, 20);
                boolElement.defaultOn = GUI.Toggle(pos, boolElement.defaultOn, "Enabled");
                position.y           += 24 + kSpacing + 10;
            }
        }

        // Item options
        if (node != null)
        {
            List <PuzzleItem> itemsInNode = puzzle.GetDefaultItemsInNode(node);

            ItemData[] itemDatas = puzzleFront.itemPrefab.items;
            foreach (var data in itemDatas)
            {
                position = new Rect(kBorder + kSpacing, position.y, 32, 48);

                DrawSprite(position, data.image);

                List <PuzzleItem> itemsOfType = itemsInNode.Where(e => e.GetType() == data.type).ToList();

                position.x    += position.width + kSpacing + 1;
                position.width = 33;
                GUI.Label(position, itemsOfType.Count.ToString());

                Rect buttonRect = position;
                buttonRect.y      += 8;
                buttonRect.height -= 16;
                buttonRect.x      += buttonRect.width + kSpacing;
                GUI.enabled        = (itemsOfType.Count > 0);
                if (GUI.Button(buttonRect, "-"))
                {
                    puzzle.RemoveItem(itemsOfType[0]);
                }
                GUI.enabled = true;

                buttonRect.x += buttonRect.width + kSpacing;
                if (GUI.Button(buttonRect, "+"))
                {
                    PuzzleItem item = (PuzzleItem)Activator.CreateInstance(data.type);
                    item.defaultNode = node;
                    puzzle.AddItem(item);
                }

                position.y += 48 - 8;
            }
        }
    }
Example #28
0
 public void AddItem(PuzzleItem item)
 {
     items.Add(item);
     addItem(item);
 }
Example #29
0
 public void RemoveItem(PuzzleItem item)
 {
     items.Remove(item);
     removeItem(item);
 }
Example #30
0
        public PuzzleItem spawnItem()
        {
            _numSpawned++;

            PuzzleItem itemToReturn = new PuzzleItem(_className);
            List<string> mutables;
            if (_properties.ContainsKey("mutables"))
                mutables = _properties["mutables"] as List<string>;
            else
                mutables = new List<string>();

            // Copy properties from the dbitem to the output item
            foreach (string propertyName in _properties.Keys) {
                if (!mutables.Contains(propertyName))
                    itemToReturn.setProperty(propertyName, _properties[propertyName]);
            }

            return itemToReturn;
        }
Example #31
0
    protected SpawnedPuzzleItem spawnItem(PuzzleItem item)
    {
        GameObject newObj = GameObject.Instantiate(PlayState.instance.puzzleItemPrefab) as GameObject;
        SpawnedPuzzleItem spawnedItem = newObj.GetComponent<SpawnedPuzzleItem>();
        // Give the spawned item all the appropriate properties.
        foreach (string propertyName in item.getPropertyNames()) {
            spawnedItem.setProperty(propertyName, item.getProperty(propertyName));
        }

        if (_game.getRequest(spawnedItem.itemName) != null)
            spawnedItem.initRequest(_game.getRequest(spawnedItem.itemName));

        return spawnedItem;
    }
Example #32
0
 private void Load(PuzzleItem item)
 {
     this.DataContext = item;
     this.puzzleItem  = item;
 }
Example #33
0
    protected void addAuxiliaryRelationship(string name1, string name2)
    {
        IRelationship relToAdd = null;

        DBItem dbitem1 = Database.Instance.getItem(name1);
        DBItem dbitem2 = Database.Instance.getItem(name2);

        // Figure out if one of the items can be inserted in the other
        if (dbitem1.propertyExists("container") && (bool)dbitem1.getProperty("container") &&
            dbitem1.propertyExists("filledby") && (dbitem1.getProperty("filledby") as List <string>).Contains(name2))
        {
            relToAdd = new InsertionRelationship(name2, 0, name1, 0);
        }
        if (relToAdd == null)
        {
            if (dbitem2.propertyExists("container") && (bool)dbitem2.getProperty("container") &&
                dbitem2.propertyExists("filledby") && (dbitem2.getProperty("filledby") as List <string>).Contains(name1))
            {
                relToAdd = new InsertionRelationship(name1, 0, name2, 0);
            }
        }
        // Next, try combine relationships
        if (relToAdd == null)
        {
            if (dbitem1.propertyExists("makes"))
            {
                List <KeyValuePair <string, string> > makes = new List <KeyValuePair <string, string> >((List <KeyValuePair <string, string> >)dbitem1.getProperty("makes"));
                Globals.shuffle(makes);
                foreach (KeyValuePair <string, string> recipe in makes)
                {
                    if (recipe.Key == name2)
                    {
                        if (!Database.Instance.itemExists(recipe.Value))
                        {
                            continue;
                        }
                        DBItem dbResult = Database.Instance.getItem(recipe.Value);
                        if (dbResult.Spawned)
                        {
                            continue;
                        }
                        PuzzleItem resultItem = dbResult.spawnItem();
                        relToAdd = new CombineRelationship(name1, 0, name2, 0, resultItem);
                        break;
                    }
                }
            }
        }
        if (relToAdd == null)
        {
            if (dbitem2.propertyExists("makes"))
            {
                List <KeyValuePair <string, string> > makes = new List <KeyValuePair <string, string> >((List <KeyValuePair <string, string> >)dbitem2.getProperty("makes"));
                Globals.shuffle(makes);
                foreach (KeyValuePair <string, string> recipe in makes)
                {
                    if (recipe.Key == name1)
                    {
                        if (!Database.Instance.itemExists(recipe.Value))
                        {
                            continue;
                        }
                        DBItem dbResult = Database.Instance.getItem(recipe.Value);
                        if (dbResult.Spawned)
                        {
                            continue;
                        }
                        PuzzleItem resultItem = dbResult.spawnItem();
                        relToAdd = new CombineRelationship(name1, 0, name2, 0, resultItem);
                        break;
                    }
                }
            }
        }
        // Finally try property change relationships
        if (relToAdd == null)
        {
            if (dbitem1.propertyExists("changes"))
            {
                List <KeyValuePair <string, string> > changes     = new List <KeyValuePair <string, string> >();
                Dictionary <string, List <string> >   changesDict = (Dictionary <string, List <string> >)dbitem1.getProperty("changes");
                foreach (string changeProp in changesDict.Keys)
                {
                    foreach (string changeVal in changesDict[changeProp])
                    {
                        changes.Add(new KeyValuePair <string, string>(changeProp, changeVal));
                    }
                }

                Globals.shuffle(changes);
                foreach (KeyValuePair <string, string> change in changes)
                {
                    // Check if the property is mutable and allows our value
                    if (!dbitem2.propertyExists("mutables") || !((List <string>)dbitem2.getProperty("mutables")).Contains(change.Key))
                    {
                        continue;
                    }
                    if (!dbitem2.propertyExists(change.Key) || !((List <string>)dbitem2.getProperty(change.Key)).Contains(change.Value))
                    {
                        continue;
                    }
                    relToAdd = new PropertyChangeRelationship(name2, 0, name1, 0, change.Key, change.Value);
                    break;
                }
            }
        }
        if (relToAdd == null)
        {
            if (dbitem2.propertyExists("changes"))
            {
                List <KeyValuePair <string, string> > changes     = new List <KeyValuePair <string, string> >();
                Dictionary <string, List <string> >   changesDict = (Dictionary <string, List <string> >)dbitem2.getProperty("changes");
                foreach (string changeProp in changesDict.Keys)
                {
                    foreach (string changeVal in changesDict[changeProp])
                    {
                        changes.Add(new KeyValuePair <string, string>(changeProp, changeVal));
                    }
                }
                Globals.shuffle(changes);
                foreach (KeyValuePair <string, string> change in changes)
                {
                    // Check if the property is mutable and allows our value
                    if (!dbitem1.propertyExists("mutables") || !((List <string>)dbitem1.getProperty("mutables")).Contains(change.Key))
                    {
                        continue;
                    }
                    if (!dbitem1.propertyExists(change.Key) || !((List <string>)dbitem1.getProperty(change.Key)).Contains(change.Value))
                    {
                        continue;
                    }
                    relToAdd = new PropertyChangeRelationship(name1, 0, name2, 0, change.Key, change.Value);
                    break;
                }
            }
        }

        if (relToAdd != null)
        {
            if (!_relationshipMap.ContainsKey(name1))
            {
                _relationshipMap[name1] = new Dictionary <string, IRelationship>();
            }
            _relationshipMap[name1][name2] = relToAdd;
            if (!_relationshipMap.ContainsKey(name2))
            {
                _relationshipMap[name2] = new Dictionary <string, IRelationship>();
            }
            _relationshipMap[name2][name1] = relToAdd;
        }
    }