Exemplo n.º 1
0
 public static string GetShopName(ScriptInstruction si)
 {
     if (si.Label.Contains("FCCSHOP"))
     {
         return("Spend company credits (items)");
     }
     else if (si.Label == "MOBSHOP1")
     {
         return("Exchange Centurio Seals");
     }
     else if (si.Label == "MOBSHOP2")
     {
         return("Exchange Centurio Seals (Advanced)");
     }
     else if (si.Label == "SHOP_SPOIL")
     {
         return("Exchange Spoils");
     }
     else if (si.Label == "SPECIAL_SHOP0" && si.Argument == 1769813)
     {
         return("Achievement Rewards");
     }
     else if (si.Label == "SPECIAL_SHOP1" && si.Argument == 1769845)
     {
         return("Achievement Rewards 2");
     }
     else if (si.Label == "SPECIAL_SHOP2" && si.Argument == 1769846)
     {
         return("Achievement Rewards 3");
     }
     else if (si.Label == "SHOP_0" && si.Argument == 1769842)
     {
         return("Gold Certificates of Commendation");
     }
     else if (si.Label == "SHOP_1" && si.Argument == 1769841)
     {
         return("Silver Certificates of Commendation");
     }
     else if (si.Label == "SHOP" && si.Argument == 1769812)
     {
         return("PVP Rewards");
     }
     else if (si.Label == "REPLICA_SHOP0" && si.Argument == 262918)
     {
         return("Purchase a Eureka weapon replica (DoW).");
     }
     else if (si.Label == "REPLICA_SHOP1" && si.Argument == 262922)
     {
         return("Purchase a Eureka weapon replica (DoM).");
     }
     else if (si.Label == "FREE_SHOP_BATTLE" && si.Argument == 1769898)
     {
         return("Battle Achievement Rewards");
     }
     else if (si.Label == "FREE_SHOP_PVP" && si.Argument == 1769899)
     {
         return("PvP Achievement Rewards");
     }
     else if (si.Label == "FREE_SHOP_CHARACTER" && si.Argument == 1769900)
     {
         return("Character Achievement Rewards");
     }
     else if (si.Label == "FREE_SHOP_ITEM" && si.Argument == 1769901)
     {
         return("Item Achievement Rewards");
     }
     else if (si.Label == "FREE_SHOP_CRAFT" && si.Argument == 1769902)
     {
         return("Crafting Achievement Rewards");
     }
     else if (si.Label == "FREE_SHOP_GATHERING" && si.Argument == 1769903)
     {
         return("Gathering Achievement Rewards");
     }
     else if (si.Label == "FREE_SHOP_QUEST" && si.Argument == 1769904)
     {
         return("Quest Achievement Rewards");
     }
     else if (si.Label == "FREE_SHOP_EXPLORATION" && si.Argument == 1769905)
     {
         return("Exploration Achievement Rewards");
     }
     else if (si.Label == "FREE_SHOP_GRANDCOMPANY" && si.Argument == 1769906)
     {
         return("Grand Company Achievement Rewards");
     }
     else
     {
         DatabaseBuilder.PrintLine($"Unknown shop label {si.Label}, arg {si.Argument}.");
         return(si.Label);
     }
 }
Exemplo n.º 2
0
        void BuildQuests()
        {
            var lQuestsByKey = _builder.Libra.Table <Libra.Quest>().ToDictionary(q => q.Key);

            foreach (var sQuest in _builder.Sheet <Saint.Quest>())
            {
                if (sQuest.Key == 65536 || sQuest.Name == "")
                {
                    continue; // Test quests
                }
                dynamic quest = new JObject();
                quest.id = sQuest.Key;
                _builder.Localize.Strings((JObject)quest, sQuest, Utils.SanitizeQuestName, "Name");
                quest.patch = PatchDatabase.Get("quest", sQuest.Key);
                quest.sort  = sQuest.SortKey;

                // Quest location
                var questIssuer = (sQuest.IssuingENpc?.Locations?.Count() ?? 0) > 0 ? sQuest.IssuingENpc : null;
                var sPlaceName  = sQuest.PlaceName;
                if (sPlaceName.Name == "" && questIssuer != null)
                {
                    sPlaceName = questIssuer.Locations.First().PlaceName;
                }

                _builder.Localize.Column((JObject)quest, sPlaceName, "Name", "location",
                                         x => x == "" ? "???" : x.ToString());

                // Repeatability
                if (sQuest.RepeatInterval == Saint.QuestRepeatInterval.Daily)
                {
                    quest.interval = "daily";
                }
                else if (sQuest.RepeatInterval == Saint.QuestRepeatInterval.Weekly)
                {
                    quest.interval = "weekly";
                }

                if (sQuest.IsRepeatable)
                {
                    quest.repeatable = 1;
                }

                // Miscellaneous
                if (sQuest.Icon != null)
                {
                    quest.icon = IconDatabase.EnsureEntry("quest", sQuest.Icon);
                }

                if (sQuest.BeastTribe.Key != 0)
                {
                    quest.beast = sQuest.BeastTribe.Key;
                }

                ImportQuestEventIcon(quest, sQuest);

                // Quest issuer
                if (questIssuer != null)
                {
                    var npc = AddQuestNpc(quest, questIssuer);
                    if (npc != null)
                    {
                        quest.issuer = questIssuer.Key;
                    }
                }

                // Quest target
                var questTarget = sQuest.TargetENpc;
                if (questTarget != null)
                {
                    var npc = AddQuestNpc(quest, questTarget);
                    if (npc != null)
                    {
                        quest.target = questTarget.Key;
                    }
                }

                // Involved
                if (_npcsByQuestKey.TryGetValue(sQuest.Key, out var involvedNpcKeys))
                {
                    foreach (var npcKey in involvedNpcKeys)
                    {
                        var sInvolvedEnpc = _builder.Realm.GameData.ENpcs[npcKey];
                        if (sInvolvedEnpc == null || sInvolvedEnpc == questTarget || sInvolvedEnpc == questIssuer)
                        {
                            continue;
                        }

                        var npc = AddQuestNpc(quest, sInvolvedEnpc);
                        if (npc == null)
                        {
                            continue;
                        }

                        if (quest.involved == null)
                        {
                            quest.involved = new JArray();
                        }
                        quest.involved.Add(npcKey);
                    }
                }

                // Journal Genre
                quest.genre = sQuest.JournalGenre.Key;

                // Rewards
                dynamic rewards = new JObject();
                if (sQuest.Rewards.Gil > 0)
                {
                    rewards.gil = sQuest.Rewards.Gil;
                }

                if (sQuest.Rewards.Emote.Key > 0)
                {
                    rewards.emote = sQuest.Rewards.Emote.Name.ToString();
                }

                if (sQuest.Rewards.ClassJob.Key > 0)
                {
                    rewards.job = sQuest.Rewards.ClassJob.Key;
                }

                if (sQuest.AsInt32("CurrencyRewardCount") > 0)
                {
                    rewards.gcseal = sQuest.AsInt32("CurrencyRewardCount");
                }

                if (sQuest.Rewards.Action.Key > 0)
                {
                    rewards.action = sQuest.Rewards.Action.Key;

                    _builder.Db.AddReference(quest, "action", sQuest.Rewards.Action.Key, false);
                }

                var sInstanceContentReward = sQuest.Rewards.InstanceContent;
                if (sInstanceContentReward.Key > 0)
                {
                    var instance = _builder.Db.Instances.FirstOrDefault(i => i.id == sInstanceContentReward.Key);
                    if (instance != null)
                    {
                        instance.unlockedByQuest = sQuest.Key;
                        rewards.instance         = sInstanceContentReward.Key;

                        _builder.Db.AddReference(quest, "instance", sInstanceContentReward.Key, false);
                        _builder.Db.AddReference(instance, "quest", sQuest.Key, false);
                    }
                }

                if (sQuest.Rewards.Reputation > 0)
                {
                    rewards.reputation = sQuest.Rewards.Reputation;
                }

                if (sQuest.Rewards.QuestRewardOther.Name == "Aether Current")
                {
                    rewards.aetherCurrent = 1;
                }

                foreach (var sQuestRewardItemGroup in sQuest.Rewards.Items)
                {
                    foreach (var sQuestRewardItem in sQuestRewardItemGroup.Items)
                    {
                        if (rewards.items == null)
                        {
                            rewards.items = new JArray();
                        }

                        var maxCount = sQuestRewardItem.Counts.Max();

                        dynamic o = new JObject();
                        if (maxCount > 1)
                        {
                            o.num = maxCount;
                        }
                        o.id = sQuestRewardItem.Item.Key;

                        if (sQuestRewardItemGroup.Type == Saint.QuestRewardGroupType.One)
                        {
                            o.one = 1;
                        }

                        if (sQuestRewardItem.IsHq)
                        {
                            o.hq = 1;
                        }

                        rewards.items.Add(o);

                        try
                        {
                            var item = _builder.Db.ItemsById[sQuestRewardItem.Item.Key];
                            if (item.quests == null)
                            {
                                item.quests = new JArray();
                            }
                            JArray quests = item.quests;

                            if (!quests.Any(id => ((int)id) == sQuest.Key))
                            {
                                quests.Add(sQuest.Key);
                            }
                            _builder.Db.AddReference(item, "quest", sQuest.Key, false);
                        }
                        catch (KeyNotFoundException ignored)
                        {
                            DatabaseBuilder.PrintLine($"Reward item '{sQuestRewardItem.Item.Key}' not found for Quest '{quest.Key}'.");
                        }

                        _builder.Db.AddReference(quest, "item", sQuestRewardItem.Item.Key, false);
                    }
                }

                // Libra supplemental rewards.
                if (lQuestsByKey.TryGetValue(sQuest.Key, out var lQuest))
                {
                    dynamic data = JsonConvert.DeserializeObject(lQuest.data);
                    int     xp   = 0;
                    if (data.exp != null && int.TryParse((string)data.exp, out xp))
                    {
                        rewards.xp = xp;
                    }
                }

                // Scripts
                var instructions = ScriptInstruction.Read(sQuest, 50);

                // Script instance unlocks.
                if (!sQuest.IsRepeatable)
                {
                    var instanceReferences = instructions.Where(i => i.Label.StartsWith("INSTANCEDUNGEON")).ToArray();
                    foreach (var instanceReference in instanceReferences)
                    {
                        var key      = (int)instanceReference.Argument;
                        var instance = _builder.Db.Instances.FirstOrDefault(i => ((int)i.id) == key);
                        if (instance == null)
                        {
                            continue; // Probably a guildhest.
                        }
                        if (instance.unlockedByQuest != null)
                        {
                            continue;
                        }

                        if (!instructions.Any(i => i.Label == "UNLOCK_ADD_NEW_CONTENT_TO_CF" || i.Label.StartsWith("UNLOCK_DUNGEON")))
                        {
                            // Some quests reference instances for the retrieval of items.
                            // Don't treat these as unlocks.
                            if (instructions.Any(i => i.Label.StartsWith("LOC_ITEM")))
                            {
                                continue;
                            }
                        }

                        instance.unlockedByQuest = sQuest.Key;
                        rewards.instance         = key;

                        _builder.Db.AddReference(quest, "instance", key, false);
                        _builder.Db.AddReference(instance, "quest", sQuest.Key, false);
                    }
                }

                // Used items.
                foreach (var instruction in instructions)
                {
                    if (!instruction.Label.StartsWith("RITEM") && !instruction.Label.StartsWith("QUEST_ITEM"))
                    {
                        continue;
                    }

                    var key = (int)instruction.Argument;
                    if (_builder.Db.ItemsById.TryGetValue(key, out var item))
                    {
                        if (item.usedInQuest == null)
                        {
                            item.usedInQuest = new JArray();
                        }

                        JArray usedInQuest = item.usedInQuest;
                        if (usedInQuest.Any(i => (int)i == sQuest.Key))
                        {
                            continue;
                        }

                        item.usedInQuest.Add(sQuest.Key);

                        if (quest.usedItems == null)
                        {
                            quest.usedItems = new JArray();
                        }
                        quest.usedItems.Add(key);

                        _builder.Db.AddReference(item, "quest", sQuest.Key, false);
                        _builder.Db.AddReference(quest, "item", key, false);
                    }
                }

                ImportQuestLore(quest, sQuest, instructions);

                if (((JObject)rewards).Count > 0)
                {
                    quest.reward = rewards;
                }

                ImportQuestRequirements(quest, sQuest);

                _builder.Db.Quests.Add(quest);
                _builder.Db.QuestsById[sQuest.Key] = quest;
            }
        }
Exemplo n.º 3
0
        private void OptimiseIncrementsAndDecrements(int iIndex)
        {
            // ADD var, 1   =>   INC var

            // ADD var, -1  =>   DEC var

            // SUB var, 1   =>   DEC var

            // SUB var, -1  =>   INC var

            ScriptInstruction scriptInstruction
                = m_scriptExecutable.InstructionsInternal[iIndex];

            // must be ADD or SUB
            if (scriptInstruction.Opcode != Opcode.ADD &&
                scriptInstruction.Opcode != Opcode.SUB)
            {
                return;
            }

            // destination must be simple or array variable
            if (scriptInstruction.Operand0.Type != OperandType.Variable &&
                scriptInstruction.Operand0.Type != OperandType.LiteralIndexedVariable &&
                scriptInstruction.Operand0.Type != OperandType.VariableIndexedVariable)
            {
                return;
            }

            // source must be literal
            if (scriptInstruction.Operand1.Type != OperandType.Literal)
            {
                return;
            }

            // source literal must be numeric
            object objectLiteral = scriptInstruction.Operand1.Value;
            Type   typeLiteral   = objectLiteral.GetType();

            if (typeLiteral != typeof(int) && typeLiteral != typeof(float))
            {
                return;
            }

            // if int literal, value must be 1 or -1
            if (typeLiteral == typeof(int) && Math.Abs((int)objectLiteral) != 1)
            {
                return;
            }

            // if float literal, value must be 1.0 or -1.0
            if (typeLiteral == typeof(float) && Math.Abs((float)objectLiteral) != 1.0f)
            {
                return;
            }

            InsertOptimiserInfo(iIndex, "Increment/Decrement Optimisation");

            float fValue = 0.0f;

            if (typeLiteral == typeof(int))
            {
                // int
                fValue = (float)(int)objectLiteral;
            }
            else
            {
                // floar
                fValue = (float)objectLiteral;
            }


            Opcode opcodeOld  = scriptInstruction.Opcode;
            bool   bIncrement = opcodeOld == Opcode.ADD && fValue > 0.0f ||
                                opcodeOld == Opcode.SUB && fValue < 0.0f;

            scriptInstruction.Opcode   = bIncrement ? Opcode.INC : Opcode.DEC;
            scriptInstruction.Operand1 = null;

            m_bOptimisationComplete = false;
        }
Exemplo n.º 4
0
 public void Write(ScriptInstruction instruction)
 {
     base.Write((byte)instruction);
 }
Exemplo n.º 5
0
        private void EliminateSelfAssignments(int iIndex)
        {
            // MOV v, v             => NOP
            // or
            // MOV v1[v2], v1[v2]   => NOP
            // or
            // MOV v[lit], v[lit]   => NOP

            ScriptInstruction scriptInstruction
                = m_scriptExecutable.InstructionsInternal[iIndex];

            // must be MOV
            if (scriptInstruction.Opcode != Opcode.MOV)
            {
                return;
            }

            // dest and source must be same type
            Operand operand0 = scriptInstruction.Operand0;
            Operand operand1 = scriptInstruction.Operand1;

            if (operand0.Type != operand1.Type)
            {
                return;
            }

            // dest and source must be simple or array ref
            if (operand0.Type != OperandType.Variable &&
                operand0.Type != OperandType.LiteralIndexedVariable &&
                operand1.Type != OperandType.VariableIndexedVariable)
            {
                return;
            }

            // simple or array ids must be same
            if (operand0.Value.ToString() != operand1.Value.ToString())
            {
                return;
            }

            // match indices if applicable
            switch (operand0.Type)
            {
            case OperandType.LiteralIndexedVariable:
                if (operand0.IndexLiteral.ToString()
                    != operand1.IndexLiteral.ToString())
                {
                    return;
                }
                break;

            case OperandType.VariableIndexedVariable:
                if (operand0.IndexIdentifier != operand1.IndexIdentifier)
                {
                    return;
                }
                break;
            }

            InsertOptimiserInfo(iIndex, "Self Assignment Removal");

            scriptInstruction.Opcode   = Opcode.NOP;
            scriptInstruction.Operand0 = null;
            scriptInstruction.Operand1 = null;

            m_bOptimisationComplete = false;
        }
Exemplo n.º 6
0
        private void OptimiseArrayIndices(int iIndex)
        {
            // MOV tmp, (idx)         =>   MOV var(idx), (expr)
            // MOV var[tmp], (expr)        NOP

            List <ScriptInstruction> listInstructions
                = m_scriptExecutable.InstructionsInternal;

            ScriptInstruction scriptInstruction0
                = listInstructions[iIndex];
            ScriptInstruction scriptInstruction1
                = listInstructions[iIndex + 1];

            // opcode check
            if (scriptInstruction0.Opcode != Opcode.MOV)
            {
                return;
            }
            if (scriptInstruction1.Opcode != Opcode.MOV)
            {
                return;
            }

            // verify idx is simple variable
            if (scriptInstruction0.Operand1.Type != OperandType.Variable)
            {
                return;
            }

            // check position of dest array
            if (scriptInstruction1.Operand0.Type
                != OperandType.VariableIndexedVariable)
            {
                return;
            }

            // specific vars are tmps
            if (!IsTemporaryVariable(scriptInstruction0.Operand0))
            {
                return;
            }
            if (!IsTemporaryVariableIndex(scriptInstruction1.Operand0))
            {
                return;
            }

            // must be same tmps
            if (scriptInstruction0.Operand0.Value.ToString()
                != scriptInstruction1.Operand0.IndexIdentifier)
            {
                return;
            }

            InsertOptimiserInfo(iIndex, "Array Index");

            scriptInstruction0.Operand0 = scriptInstruction1.Operand0;
            scriptInstruction0.Operand0.IndexIdentifier
                = scriptInstruction0.Operand1.Value.ToString();
            scriptInstruction0.Operand1 = scriptInstruction1.Operand1;
            scriptInstruction1.Opcode   = Opcode.NOP;
            scriptInstruction1.Operand0 = null;
            scriptInstruction1.Operand1 = null;

            m_bOptimisationComplete = false;
        }
Exemplo n.º 7
0
        private void OptimiseBinaryExpressionAssignment(int iIndex)
        {
            // MOV  tmp, (src0)        MOV  dest, (src0)
            // (OP) tmp, (src1)   =>   (OP) dest, (src1)
            // MOV  dest, tmp          NOP

            List <ScriptInstruction> listInstructions
                = m_scriptExecutable.InstructionsInternal;

            ScriptInstruction scriptInstruction0
                = listInstructions[iIndex];
            ScriptInstruction scriptInstruction1
                = listInstructions[iIndex + 1];
            ScriptInstruction scriptInstruction2
                = listInstructions[iIndex + 2];

            // opcode matches
            if (scriptInstruction0.Opcode != Opcode.MOV)
            {
                return;
            }
            if (!IsBinaryOperator(scriptInstruction1.Opcode))
            {
                return;
            }
            if (scriptInstruction2.Opcode != Opcode.MOV)
            {
                return;
            }

            // specific variables are tmps
            if (!IsTemporaryVariable(scriptInstruction0.Operand0))
            {
                return;
            }
            if (!IsTemporaryVariable(scriptInstruction1.Operand0))
            {
                return;
            }
            if (!IsTemporaryVariable(scriptInstruction2.Operand1))
            {
                return;
            }

            // same tmp ids
            if (scriptInstruction0.Operand0.Value.ToString()
                != scriptInstruction1.Operand0.Value.ToString())
            {
                return;
            }
            if (scriptInstruction0.Operand0.Value.ToString()
                != scriptInstruction2.Operand1.Value.ToString())
            {
                return;
            }

            InsertOptimiserInfo(iIndex, "Binary Expression Assignment");

            scriptInstruction0.Operand0 = scriptInstruction2.Operand0;
            scriptInstruction1.Operand0 = scriptInstruction2.Operand0;
            scriptInstruction2.Opcode   = Opcode.NOP;
            scriptInstruction2.Operand0 = null;
            scriptInstruction2.Operand1 = null;

            m_bOptimisationComplete = false;
        }
Exemplo n.º 8
0
    void UpdateText(int score)
    {
        string scriptString = "";

        // Get newLocation
        newLocation = startingPoint + journeyDirection * score;
        int x = (int)newLocation.x;
        int y = (int)newLocation.y;

        // Debug.Log(newLocation);

        // Get string
        scriptString = script[x, y];

        // Parse string
        string[] splitArray  = scriptString.Split(new string[] { "#" }, StringSplitOptions.RemoveEmptyEntries);
        string   defaultText = splitArray[0];

        ScriptInstruction[] instructions = new ScriptInstruction[splitArray.Length - 1];

        for (int i = 0; i < splitArray.Length - 1; i++)
        {
            string[] toParse = splitArray[i + 1].Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);

            if (toParse[0].Contains("?"))
            {
                instructions[i].condition = toParse[0];
                instructions[i].actions   = toParse[1].Split(new string[] { "*" }, StringSplitOptions.RemoveEmptyEntries);
            }
            else
            {
                instructions[i].condition = "";
                instructions[i].actions   = toParse[0].Split(new string[] { "*" }, StringSplitOptions.RemoveEmptyEntries);
            }
        }

        flavourText.text = defaultText;



        // Check instructions

        for (int i = 0; i < instructions.Length; i++)
        {
            // visited current location
            if (instructions[i].condition.Contains("?hVL"))
            {
                bool v = instructions[i].condition.Contains("==T") ? true : false;

                if (hasVisited[x, y] == v)
                {
                    CheckActions(instructions[i].actions);
                }
            }

            // inventory look up
            if (instructions[i].condition.Contains("?iLU"))
            {
                bool   v            = instructions[i].condition.Contains("==T") ? true : false;
                string itemToLookUp = instructions[i].condition.Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries)[1];

                if (inventoryLookUp[itemToLookUp] == v)
                {
                    CheckActions(instructions[i].actions);
                }
            }

            // check Journey Direction
            if (instructions[i].condition.Contains("?cJD"))
            {
                Vector2 v = Vector2.zero;

                switch (instructions[i].condition.Replace("?cJD==", ""))
                {
                case "up":
                    v = Vector2.up;
                    break;

                case "down":
                    v = Vector2.down;
                    break;

                case "right":
                    v = Vector2.right;
                    break;

                case "left":
                    v = Vector2.left;
                    break;
                }

                if (journeyDirection == v)
                {
                    CheckActions(instructions[i].actions);
                }
            }

            if (instructions[i].condition == "")
            {
                CheckActions(instructions[i].actions);
            }
        }



        // Update Text
        // flavourText.text = newText;

        // Update Metrics
        hasVisited[x, y] = true;
        locationVisitTimes[x, y]++;
    }
Exemplo n.º 9
0
        dynamic ImportInstruction(ScriptInstruction instruction)
        {
            // Not currently used.

            dynamic ins = new JObject();

            ins.text = instruction.Label;

            var arg = (int)instruction.Argument;

            if (instruction.Argument > 0)
            {
                ins.arg = instruction.Argument;
            }

            string refname = null;

            if (instruction.Label.StartsWith("ACTOR") ||
                instruction.Label.StartsWith("LOC_ACTOR"))
            {
                ins.type = "npc";
                if (arg == 5010000) // From EventSystemDefine?
                {
                    refname = "Player";
                }
                else if (!_builder.Db.NpcsById.ContainsKey(arg))
                {
                    var sENpcs = _builder.Sheet <Saint.ENpcResident>();
                    if (sENpcs.ContainsRow(arg))
                    {
                        refname = Utils.CapitalizeWords(sENpcs[arg].Singular.ToString());
                    }
                }
            }
            else if (instruction.Label.StartsWith("ITEM") ||
                     instruction.Label.StartsWith("RITEM"))
            {
                ins.type = "item";
                if (!_builder.Db.ItemsById.ContainsKey(arg))
                {
                    refname = _builder.Realm.GameData.Items[arg].Name.ToString();
                }
            }
            else if (instruction.Label.StartsWith("INSTANCEDUNGEON"))
            {
                ins.type = "instance";
                if (!_builder.Db.InstancesById.ContainsKey(arg))
                {
                    refname = _builder.Sheet <Saint.InstanceContent>()[arg].Name.ToString();
                }
            }
            else if (instruction.Label.StartsWith("ENEMY"))
            {
                ins.type = "mob";
                if (!_builder.Db.MobsById.ContainsKey(arg))
                {
                    var bnpcs = _builder.Sheet <Saint.BNpcName>();
                    if (bnpcs.ContainsRow(arg))
                    {
                        refname = Utils.CapitalizeWords(bnpcs[arg].Singular.ToString());
                    }
                    // else possible Level reference - location?
                }
            }
            else if (instruction.Label.StartsWith("EOBJECT"))
            {
                //ins.type = "object";
                var eventitems = _builder.Sheet <Saint.EventItem>();
                if (eventitems.ContainsRow(arg))
                {
                    refname = eventitems[arg].Name.ToString();
                }
            }
            else if (instruction.Label.StartsWith("TERRITORYTYPE"))
            {
                var territoryType = _builder.Sheet <Saint.TerritoryType>()[arg];
                refname = territoryType.PlaceName.ToString();
            }
            else if (instruction.Label.Contains("EMOTE") ||
                     instruction.Label.StartsWith("MOTION") ||
                     instruction.Label == "EVENT_ACTION_" ||
                     instruction.Label.StartsWith("LOC_FACE"))
            {
                _builder.EmoteNamesById.TryGetValue(arg, out refname);
            }
            else if (instruction.Label.StartsWith("LOC_ACTION"))
            {
                ins.type = "action";
                if (_builder.Db.ActionsById.ContainsKey(arg))
                {
                    refname = _builder.Db.ActionsById[arg].name;
                }
                else
                {
                    var sActions = _builder.Sheet <Saint.Action>();
                    if (sActions.ContainsRow(arg))
                    {
                        refname = sActions[arg].Name.ToString();
                    }
                    else
                    {
                        refname = "Unknown";
                    }
                }
            }

            if (!string.IsNullOrEmpty(refname))
            {
                ins.refname = refname;
            }

            return(ins);
        }