Ejemplo n.º 1
0
        public static TES5EventCodeBlock CreateOnInit()
        {
            TES5FunctionScope  onInitFunctionScope = TES5FunctionScopeFactory.CreateFromBlockType("OnInit");
            TES5EventCodeBlock newInitBlock        = new TES5EventCodeBlock(onInitFunctionScope, TES5CodeScopeFactory.CreateCodeScopeRoot(onInitFunctionScope));

            return(newInitBlock);
        }
Ejemplo n.º 2
0
        public static TES5StateCodeBlock CreateState(string name, bool auto)
        {
            TES5FunctionScope  functionScope = new TES5FunctionScope(name);
            TES5CodeScope      codeScope     = TES5CodeScopeFactory.CreateCodeScopeRoot(functionScope);
            TES5StateCodeBlock state         = new TES5StateCodeBlock(name, auto, functionScope, codeScope);

            return(state);
        }
Ejemplo n.º 3
0
        public static TES5EventCodeBlock CreateEventCodeBlock(TES5FunctionScope functionScope, TES5GlobalScope globalScope)
        {
            InferEventBlockContainingType(functionScope.BlockName, globalScope);
            TES5CodeScope      codeScope = TES5CodeScopeFactory.CreateCodeScopeRoot(functionScope);
            TES5EventCodeBlock newBlock  = new TES5EventCodeBlock(functionScope, codeScope);

            return(newBlock);
        }
Ejemplo n.º 4
0
 public TES5FunctionCodeBlock(TES5FunctionScope functionScope, TES5CodeScope codeScope, ITES5Type returnType, bool isStandalone, bool isQuestFragmentOrTopicFragment)
 {
     this.FunctionScope = functionScope;
     this.CodeScope     = codeScope;
     this.returnType    = returnType;
     this.isStandalone  = isStandalone;
     this.isQuestFragmentOrTopicFragment = isQuestFragmentOrTopicFragment;
 }
Ejemplo n.º 5
0
 public TES5State(string name, bool auto, TES5FunctionScope functionScope, TES5CodeScope codeScope)
 {
     this.name          = name;
     this.auto          = auto;
     this.FunctionScope = functionScope;
     this.CodeScope     = codeScope;
     codeBlocks         = new TES5BlockList();
 }
Ejemplo n.º 6
0
        public TES5BlockList CreateBlock(TES4CodeBlock block, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope, ref TES5EventCodeBlock?onUpdateBlockForNonQuestOrAME)
        {
            TES5BlockList  blockList    = new TES5BlockList();
            string         blockType    = block.BlockType;
            string         newBlockType = MapBlockType(blockType);
            TES4CodeChunks?chunks       = block.Chunks;

            if (chunks != null && chunks.Any())
            {
                TES5FunctionScope blockFunctionScope       = TES5FunctionScopeFactory.CreateFromBlockType(newBlockType);
                bool               onUpdateOfNonQuestOrAME = newBlockType == "OnUpdate" && globalScope.ScriptHeader.ScriptType.NativeType != TES5BasicType.T_QUEST && globalScope.ScriptHeader.ScriptType.NativeType != TES5BasicType.T_ACTIVEMAGICEFFECT;
                bool               onUpdateBlockOfNonQuestOrAMEAlreadyPresent = onUpdateBlockForNonQuestOrAME != null;
                TES5BlockList?     onUpdateAdditionalBlocksOfNonQuestOrAME    = null;
                TES5EventCodeBlock targetEventBlock;
                TES5CodeScope      targetCodeScope;
                if (onUpdateOfNonQuestOrAME)
                {
                    if (!onUpdateBlockOfNonQuestOrAMEAlreadyPresent)
                    {
                        CreateActivationStates(globalScope, out onUpdateAdditionalBlocksOfNonQuestOrAME, out targetEventBlock);
                        onUpdateBlockForNonQuestOrAME = targetEventBlock;
                    }
                    else
                    {
                        if (onUpdateBlockForNonQuestOrAME == null)
                        {
                            throw new NullableException(nameof(onUpdateBlockForNonQuestOrAME));
                        }
                        targetEventBlock = onUpdateBlockForNonQuestOrAME;
                    }
                    targetCodeScope = targetEventBlock.CodeScope;
                }
                else
                {
                    targetEventBlock = CreateEventCodeBlock(blockFunctionScope, globalScope);
                    targetCodeScope  = this.initialBlockCodeFactory.AddInitialCode(globalScope, targetEventBlock);
                }
                TES5CodeScope newScope           = TES5CodeScopeFactory.CreateCodeScopeRecursive(targetCodeScope.LocalScope);
                TES5CodeScope convertedCodeScope = this.ConvertTES4CodeChunksToTES5CodeScope(chunks, newScope, globalScope, multipleScriptsScope);
                TES5CodeScope modifiedCodeScope  = this.changesPass.Modify(block, blockList, blockFunctionScope, convertedCodeScope, globalScope, multipleScriptsScope);
                targetEventBlock.CodeScope.LocalScope.CopyVariablesFrom(modifiedCodeScope.LocalScope);
                targetEventBlock.CodeScope.AddChunks(modifiedCodeScope.CodeChunks);
                blockList.Add(targetEventBlock);
                if (onUpdateOfNonQuestOrAME)
                {
                    if (!onUpdateBlockOfNonQuestOrAMEAlreadyPresent)
                    {
                        if (onUpdateAdditionalBlocksOfNonQuestOrAME == null)
                        {
                            throw new NullableException(nameof(onUpdateAdditionalBlocksOfNonQuestOrAME));
                        }
                        return(onUpdateAdditionalBlocksOfNonQuestOrAME);
                    }
                    return(new TES5BlockList());
                }
            }
            return(blockList);
        }
        public static void GenerateINFOAddTopicScripts(ESMAnalyzer esmAnalyzer, BuildTracker buildTracker, IBuildTarget tifBuildTarget)
        {
            TES5TypeInferencer    typeInferencer    = new TES5TypeInferencer(esmAnalyzer);
            TES5ObjectCallFactory objectCallFactory = new TES5ObjectCallFactory(typeInferencer);
            TES4TopicsToTES5GlobalVariableFinder globalVariableFinder = new TES4TopicsToTES5GlobalVariableFinder();
            TES5GlobalVariables globalVariables = esmAnalyzer.GlobalVariables;
            var builtTIFs = buildTracker.GetBuiltScripts(BuildTargetFactory.TIFName);

            foreach (TES4Record infoRecord in esmAnalyzer.GetRecords().Where(r => r.RecordType == TES4RecordType.INFO))
            {
                TES4SubrecordData[] names = infoRecord.GetSubrecords("NAME").ToArray();
                if (names.Any())
                {
                    string                fragment0Name     = TES5FragmentFactory.GetFragmentName(0);
                    string                nameTES5FormIDHex = (infoRecord.FormID + 0x01000000).ToString("x8");
                    string                scriptName        = TES5ReferenceFactory.tif_Prefix + "_" + nameTES5FormIDHex;
                    TES5Script?           infoTIF           = builtTIFs.Where(s => s.Key == scriptName).Select(s => s.Value.Script).FirstOrDefault();
                    TES5FunctionCodeBlock fragment0;
                    if (infoTIF != null)
                    {
                        fragment0 = infoTIF.BlockList.Blocks.OfType <TES5FunctionCodeBlock>().Where(b => b.BlockName == fragment0Name).First();
                    }
                    else
                    {
                        TES5ScriptHeader  scriptHeader  = TES5ScriptHeaderFactory.GetFromCacheOrConstructByBasicType(scriptName, TES5BasicType.T_TOPICINFO, TES5TypeFactory.TES4_Prefix, true);
                        TES5GlobalScope   globalScope   = new TES5GlobalScope(scriptHeader);
                        TES5FunctionScope functionScope = new TES5FunctionScope(fragment0Name);
                        functionScope.AddParameter(new TES5SignatureParameter("akSpeakerRef", TES5BasicType.T_OBJECTREFERENCE, true));
                        TES5LocalScope localScope = new TES5LocalScope(functionScope);
                        TES5CodeScope  codeScope  = TES5CodeScopeFactory.CreateCodeScope(localScope);
                        fragment0 = new TES5FunctionCodeBlock(functionScope, codeScope, TES5VoidType.Instance, false, true);
                        TES5BlockList blockList = new TES5BlockList()
                        {
                            fragment0
                        };
                        infoTIF = new TES5Script(globalScope, blockList, true);
                        string     outputPath = tifBuildTarget.GetTranspileToPath(scriptName);
                        TES5Target target     = new TES5Target(infoTIF, outputPath);
                        buildTracker.RegisterBuiltScript(tifBuildTarget, target);
                    }
                    foreach (TES4SubrecordData name in names)
                    {
                        int                 formID                   = infoRecord.ExpandBytesIntoFormID(name);
                        TES4Record          addedTopic               = esmAnalyzer.GetRecordByFormID(formID);
                        Tuple <int, string>?globalVariable           = globalVariableFinder.GetGlobalVariableNullable(addedTopic.FormID);
                        string              globalVariableEditorID   = globalVariable != null ? globalVariable.Item2 : globalVariableFinder.GetGlobalVariableEditorID(addedTopic.GetEditorID());
                        Nullable <int>      globalVariableTES5FormID = globalVariable != null ? globalVariable.Item1 : (Nullable <int>)null;
                        TES5Property        topicAddedProperty       = TES5PropertyFactory.ConstructWithTES5FormID(globalVariableEditorID, TES5BasicType.T_GLOBALVARIABLE, globalVariableEditorID, globalVariableTES5FormID);
                        infoTIF.GlobalScope.AddPropertyIfNotExists(topicAddedProperty);
                        TES5Reference topicAddedReference = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(topicAddedProperty);
                        fragment0.AddChunk(objectCallFactory.CreateObjectCall(topicAddedReference, "SetValueInt", new TES5ObjectCallArguments()
                        {
                            new TES5Integer(1)
                        }));
                    }
                }
            }
        }
        private static void SetUpBranch(TES5FunctionScope blockFunctionScope, TES5EventCodeBlock newBlock, ITES5Value expression)
        {
            TES5CodeScope newCodeScope = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope);
            //TES5CodeScope outerBranchCode = PHPFunction.Deserialize<TES5CodeScope>(PHPFunction.Serialize(newBlock.CodeScope));//WTM:  Change:  Why serialize and then deserialize?
            TES5CodeScope outerBranchCode = newBlock.CodeScope;

            outerBranchCode.LocalScope.ParentScope = newCodeScope.LocalScope;
            newCodeScope.AddChunk(new TES5Branch(new TES5SubBranch(expression, outerBranchCode)));
            newBlock.CodeScope = newCodeScope;
        }
Ejemplo n.º 9
0
        public static TES5EventCodeBlock CreateEventCodeBlock(string blockType, TES5FunctionScope functionScope = null)
        {
            if (functionScope == null)
            {
                functionScope = new TES5FunctionScope(blockType);
            }
            TES5CodeScope      codeScope = TES5CodeScopeFactory.CreateCodeScopeRoot(functionScope);
            TES5EventCodeBlock newBlock  = new TES5EventCodeBlock(functionScope, codeScope);

            return(newBlock);
        }
Ejemplo n.º 10
0
 private readonly bool isStandalone;//Only needed for PHP_COMPAT
 public TES5FunctionCodeBlock(TES5FunctionScope functionScope, TES5CodeScope codeScope, ITES5Type returnType, bool isStandalone = false)
 {
     if (returnType == null)
     {
         throw new ArgumentNullException(nameof(returnType));
     }
     this.FunctionScope = functionScope;
     this.CodeScope     = codeScope;
     this.returnType    = returnType;
     this.isStandalone  = isStandalone;
 }
        public TES5CodeChunkCollection CreateCodeChunkCollection(TES5FunctionScope functionScope, TES5GlobalScope globalScope)
        {
            TES5CodeChunkCollection collection = new TES5CodeChunkCollection();

            if (functionScope.BlockName == "OnUpdate")
            {
                TES5ObjectCall function = this.objectCallFactory.CreateRegisterForSingleUpdate(globalScope);
                collection.Add(function);
            }
            collection.Add(new TES5Return());
            return(collection);
        }
        public static TES5FunctionScope CreateFromFragmentType(string fragmentName, TES5FragmentType fragmentType)
        {
            TES5FunctionScope localScope = new TES5FunctionScope(fragmentName);

            if (fragmentType == TES5FragmentType.T_TIF)
            {
                localScope.AddVariable(new TES5LocalVariable("akSpeakerRef", TES5BasicType.T_OBJECTREFERENCE, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));
            }
            else if (fragmentType == TES5FragmentType.T_PF)
            {
                localScope.AddVariable(new TES5LocalVariable("akActor", TES5BasicType.T_ACTOR, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));
            }
            return(localScope);
        }
Ejemplo n.º 13
0
        /*
         *  The stage ID
         *  List of integers describing targets being enabled or disabled for given stage
         */
        public TES5FunctionCodeBlock CreateEnclosedFragment(TES5GlobalScope globalScope, int stageId, List <int> stageMap)
        {
            string                fragmentName  = "Fragment_" + stageId.ToString();
            TES5FunctionScope     functionScope = TES5FragmentFunctionScopeFactory.CreateFromFragmentType(fragmentName, TES5FragmentType.T_QF);
            TES5CodeScope         codeScope     = TES5CodeScopeFactory.CreateCodeScopeRoot(functionScope);
            TES5FunctionCodeBlock codeBlock     = new TES5FunctionCodeBlock(functionScope, codeScope, new TES5VoidType());
            List <ITES5CodeChunk> chunks        = this.GenerateObjectiveHandling(codeBlock, globalScope, stageMap);

            foreach (var chunk in chunks)
            {
                codeBlock.AddChunk(chunk);
            }
            return(codeBlock);
        }
        public TES5FunctionCodeBlock CreateFragment(TES5FragmentType fragmentType, string fragmentName, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope, TES4CodeChunks chunks)
        {
            TES5FunctionScope     fragmentLocalScope = TES5FragmentFunctionScopeFactory.CreateFromFragmentType(fragmentName, fragmentType);
            TES5FunctionCodeBlock function           = new TES5FunctionCodeBlock(fragmentLocalScope, TES5CodeScopeFactory.CreateCodeScopeRoot(fragmentLocalScope), TES5VoidType.Instance, false, fragmentType == TES5FragmentType.T_QF || fragmentType == TES5FragmentType.T_TIF);

            foreach (var codeChunk in chunks)
            {
                TES5CodeChunkCollection codeChunks = this.codeChunkFactory.CreateCodeChunk(codeChunk, function.CodeScope, globalScope, multipleScriptsScope);
                foreach (var newCodeChunk in codeChunks)
                {
                    function.AddChunk(newCodeChunk);
                }
            }
            return(function);
        }
        private void SetUpBranch(TES4CodeBlock block, TES5EventCodeBlock newBlock, TES5FunctionScope blockFunctionScope, ITES5VariableOrProperty variable, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4BlockParameterList parameterList = block.BlockParameterList;

            if (parameterList == null)
            {
                return;
            }
            List <TES4BlockParameter> parameterListVariableList = parameterList.Parameters;
            TES4BlockParameter        tesEquippedTarget         = parameterListVariableList[0];
            TES5LocalScope            localScope   = newBlock.CodeScope.LocalScope;
            ITES5Referencer           newContainer = this.referenceFactory.CreateReadReference(tesEquippedTarget.BlockParameter, globalScope, multipleScriptsScope, localScope);
            TES5ComparisonExpression  expression   = TES5ExpressionFactory.CreateComparisonExpression(TES5ReferenceFactory.CreateReferenceToVariable(variable), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, newContainer);

            SetUpBranch(blockFunctionScope, newBlock, expression);
        }
Ejemplo n.º 16
0
        public TES5BlockList CreateBlock(TES4CodeBlock block, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5BlockList blockList = new TES5BlockList();
            string        blockType = block.BlockType;

            if (blockType.Equals("menumode", StringComparison.OrdinalIgnoreCase))
            {
                return(blockList);
            }
            string         newBlockType = MapBlockType(blockType);
            TES4CodeChunks chunks       = block.Chunks;

            if (chunks != null && chunks.Any())
            {
                TES5EventCodeBlock newBlock;
                bool          onUpdateOfNonQuest = newBlockType == "OnUpdate" && globalScope.ScriptHeader.BasicScriptType != TES5BasicType.T_QUEST;
                TES5BlockList onUpdateOfNonQuestAdditionalBlocks = null;
                if (onUpdateOfNonQuest)
                {
                    CreateActivationStates(globalScope, multipleScriptsScope, out onUpdateOfNonQuestAdditionalBlocks, out newBlock);
                }
                else
                {
                    TES5FunctionScope blockFunctionScope = TES5FunctionScopeFactory.CreateFromBlockType(newBlockType);
                    newBlock = CreateEventCodeBlock(newBlockType, blockFunctionScope);
                }
                this.ConvertTES4CodeChunksToTES5EventCodeBlock(chunks, newBlock, globalScope, multipleScriptsScope);
                this.changesPass.Modify(block, blockList, newBlock, globalScope, multipleScriptsScope);
                blockList.Add(newBlock);
                if (onUpdateOfNonQuest)
                {
                    return(onUpdateOfNonQuestAdditionalBlocks);
                }
            }
            return(blockList);
        }
Ejemplo n.º 17
0
        public static TES5EventCodeBlock CreateEventCodeBlock(string eventName, TES5GlobalScope globalScope)
        {
            TES5FunctionScope functionScope = new TES5FunctionScope(eventName);

            return(CreateEventCodeBlock(functionScope, globalScope));
        }
        public static TES5FunctionScope CreateFromBlockType(string blockType)
        {
            TES5FunctionScope localScope = new TES5FunctionScope(blockType);

            switch (blockType)
            {
            case "OnUpdate":
            {
                break;
            }

            case "OnActivate":
            {
                localScope.AddVariable(new TES5LocalVariable("akActivateRef", TES5BasicType.T_OBJECTREFERENCE, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));
                break;
            }

            case "OnInit":
            {
                break;
            }

            case "OnSell":
            {
                localScope.AddVariable(new TES5LocalVariable("akSeller", TES5BasicType.T_ACTOR, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));     //todo not sure about activator meaning
                break;
            }

            case "OnDeath":
            {
                localScope.AddVariable(new TES5LocalVariable("akKiller", TES5BasicType.T_ACTOR, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));
                break;
            }

            case "OnLoad":
            {
                break;
            }

            case "OnObjectEquipped":
            {
                localScope.AddVariable(new TES5LocalVariable("akBaseObject", TES5BasicType.T_FORM, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.CONTAINER }));
                localScope.AddVariable(new TES5LocalVariable("akReference", TES5BasicType.T_OBJECTREFERENCE));
                break;
            }

            case "OnTriggerEnter":
            {
                localScope.AddVariable(new TES5LocalVariable("akActivateRef", TES5BasicType.T_OBJECTREFERENCE, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR, TES5LocalVariableParameterMeaning.CONTAINER }));
                break;
            }

            case "OnEquipped":
            {
                localScope.AddVariable(new TES5LocalVariable("akActor", TES5BasicType.T_ACTOR, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR, TES5LocalVariableParameterMeaning.CONTAINER }));
                break;
            }

            case "OnUnequipped":
            {
                localScope.AddVariable(new TES5LocalVariable("akActor", TES5BasicType.T_ACTOR, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));
                break;
            }

            case "OnContainerChanged":
            {
                localScope.AddVariable(new TES5LocalVariable("akNewContainer", TES5BasicType.T_OBJECTREFERENCE));
                localScope.AddVariable(new TES5LocalVariable("akOldContainer", TES5BasicType.T_OBJECTREFERENCE));
                break;
            }

            case "OnTrigger":
            {
                localScope.AddVariable(new TES5LocalVariable("akActivateRef", TES5BasicType.T_OBJECTREFERENCE, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));
                break;
            }

            case "OnHit":
            {
                localScope.AddVariable(new TES5LocalVariable("akAggressor", TES5BasicType.T_OBJECTREFERENCE, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));
                localScope.AddVariable(new TES5LocalVariable("akSource", TES5BasicType.T_FORM));
                localScope.AddVariable(new TES5LocalVariable("akProjectile", TES5BasicType.T_PROJECTILE));
                localScope.AddVariable(new TES5LocalVariable("abPowerAttack", TES5BasicType.T_BOOL));
                localScope.AddVariable(new TES5LocalVariable("abSneakAttack", TES5BasicType.T_BOOL));
                localScope.AddVariable(new TES5LocalVariable("abBashAttack", TES5BasicType.T_BOOL));
                localScope.AddVariable(new TES5LocalVariable("abHitBlocked", TES5BasicType.T_BOOL));
                break;
            }

            case "OnCombatStateChanged":
            {
                localScope.AddVariable(new TES5LocalVariable("akTarget", TES5BasicType.T_ACTOR, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));
                localScope.AddVariable(new TES5LocalVariable("aeCombatState", TES5BasicType.T_INT));
                break;
            }

            case "OnPackageStart":
            {
                localScope.AddVariable(new TES5LocalVariable("akNewPackage", TES5BasicType.T_PACKAGE));
                break;
            }

            case "OnPackageDone":
            {
                localScope.AddVariable(new TES5LocalVariable("akDonePackage", TES5BasicType.T_PACKAGE));
                break;
            }

            case "OnPackageEnd":
            {
                localScope.AddVariable(new TES5LocalVariable("akOldPackage", TES5BasicType.T_PACKAGE));
                break;
            }

            case "OnPackageChange":
            {
                localScope.AddVariable(new TES5LocalVariable("akOldPackage", TES5BasicType.T_PACKAGE));
                break;
            }

            case "OnMagicEffectApply":
            {
                localScope.AddVariable(new TES5LocalVariable("akCaster", TES5BasicType.T_OBJECTREFERENCE, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));
                localScope.AddVariable(new TES5LocalVariable("akMagicEffect", TES5BasicType.T_MAGICEFFECT));
                break;
            }

            case "OnReset":
            {
                break;
            }

            case "OnEffectStart":
            {
                localScope.AddVariable(new TES5LocalVariable("akTarget", TES5BasicType.T_ACTOR));
                localScope.AddVariable(new TES5LocalVariable("akCaster", TES5BasicType.T_ACTOR, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));
                break;
            }

            case "OnEffectFinish":
            {
                localScope.AddVariable(new TES5LocalVariable("akTarget", TES5BasicType.T_ACTOR));
                localScope.AddVariable(new TES5LocalVariable("akCaster", TES5BasicType.T_ACTOR, new TES5LocalVariableParameterMeaning[] { TES5LocalVariableParameterMeaning.ACTIVATOR }));
                break;
            }

            default:
            {
                throw new ConversionException("Cannot find new block type local scope variables out of " + blockType);
            }
            }

            return(localScope);
        }
        /*
         *  The script to be converted
         *  The script"s global scope
         *  The scope under which we"re converting
         *
         * @throws ConversionException
         */
        public TES5Target Convert(TES4Target target, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4Script    script          = target.Script;
            TES5BlockList blockList       = new TES5BlockList();
            TES4BlockList parsedBlockList = script.BlockList;
            Dictionary <string, List <ITES5CodeBlock> > createdBlocks = new Dictionary <string, List <ITES5CodeBlock> >();

            if (parsedBlockList != null)
            {
                foreach (TES4CodeBlock block in parsedBlockList.Blocks)
                {
                    TES5BlockList newBlockList = this.blockFactory.CreateBlock(block, globalScope, multipleScriptsScope);
                    foreach (ITES5CodeBlock newBlock in newBlockList.Blocks)
                    {
                        createdBlocks.AddNewListIfNotContainsKeyAndAddValueToList(newBlock.BlockName, newBlock);
                    }
                }
            }

            //todo encapsulate it to a different class.
            bool isStandalone = target.OutputPath.Contains(Path.DirectorySeparatorChar + "Standalone" + Path.DirectorySeparatorChar);

            foreach (var createdBlock in createdBlocks)
            {
                var blockType = createdBlock.Key;
                var blocks    = createdBlock.Value;
                if (blocks.Count > 1)
                {
                    List <TES5FunctionCodeBlock> functions = new List <TES5FunctionCodeBlock>();
                    int i = 1;
                    TES5ObjectCallArguments localScopeArguments = null;
                    foreach (TES5CodeBlock block in blocks)
                    {
                        TES5FunctionScope newFunctionScope = new TES5FunctionScope(blockType + "_" + i.ToString());
                        foreach (var variable in block.FunctionScope.Variables.Values)
                        {
                            newFunctionScope.AddVariable(variable);
                        }

                        TES5FunctionCodeBlock function = new TES5FunctionCodeBlock(newFunctionScope, block.CodeScope, new TES5VoidType(), isStandalone);
                        functions.Add(function);
                        if (localScopeArguments == null)
                        {
                            localScopeArguments = new TES5ObjectCallArguments();
                            foreach (var variable in block.FunctionScope.Variables.Values)
                            {
                                localScopeArguments.Add(TES5ReferenceFactory.CreateReferenceToVariable(variable));
                            }
                        }

                        ++i;
                    }

                    //Create the proxy block.
                    ITES5CodeBlock     lastBlock  = blocks.Last();
                    TES5EventCodeBlock proxyBlock = TES5BlockFactory.CreateEventCodeBlock(blockType,

                                                                                          /*
                                                                                           * //WTM:  Change:  block was used below, but block is out of scope.  The PHP must have been using the last defined block from above.
                                                                                           * //WTM:  Change:  PHP called "clone" below, but I'm not sure if this is necessary or would even operate the same in C#.
                                                                                           */
                                                                                          lastBlock.FunctionScope);
                    foreach (var function in functions)
                    {
                        blockList.Add(function);
                        TES5ObjectCall functionCall = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), function.BlockName, multipleScriptsScope, localScopeArguments, false // hacky.
                                                                                              );
                        proxyBlock.AddChunk(functionCall);
                    }

                    blockList.Add(proxyBlock);
                }
                else
                {
                    ITES5CodeBlock block = blocks[0];
                    blockList.Add(block);
                }
            }

            TES5Target result = new TES5Target(new TES5Script(globalScope, blockList), target.OutputPath);

            return(result);
        }
Ejemplo n.º 20
0
 public static TES5CodeScope CreateCodeScopeRoot(TES5FunctionScope functionScope)
 {
     return(CreateCodeScope(TES5LocalScopeFactory.CreateRootScope(functionScope)));
 }
 private TES5CodeScope SetUpBranch(TES4CodeBlock block, TES5CodeScope codeScope, TES5FunctionScope blockFunctionScope, TES5LocalVariableParameterMeaning meaning, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
 {
     return(SetUpBranch(block, codeScope, blockFunctionScope, codeScope.LocalScope.GetVariableWithMeaning(meaning), globalScope, multipleScriptsScope));
 }
 private TES5CodeScope SetUpBranch(TES4CodeBlock block, TES5CodeScope codeScope, TES5FunctionScope blockFunctionScope, string variable, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
 {
     return(SetUpBranch(block, codeScope, blockFunctionScope, codeScope.LocalScope.GetVariable(variable), globalScope, multipleScriptsScope));
 }
 public TES5EventCodeBlock(TES5FunctionScope functionScope, TES5CodeScope codeScope)
 {
     this.FunctionScope = functionScope;
     this.CodeScope     = codeScope;
 }
 private void SetUpBranch(TES4CodeBlock block, TES5EventCodeBlock newBlock, TES5FunctionScope blockFunctionScope, TES5LocalVariableParameterMeaning variable, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
 {
     SetUpBranch(block, newBlock, blockFunctionScope, newBlock.CodeScope.LocalScope.GetVariableWithMeaning(variable), globalScope, multipleScriptsScope);
 }
Ejemplo n.º 25
0
        private IEnumerable <TES5CodeBlock> CombineRepeatedEventCodeBlockNames(List <ITES5CodeBlock> blocks, string blockType, bool isStandalone, TES5GlobalScope globalScope)
        {
            ITES5CodeBlock[] nonEvents = blocks.Where(b => !(b is TES5EventCodeBlock)).ToArray();
            if (nonEvents.Any())
            {
                throw new ConversionException("Some non-event code blocks were present in " + nameof(CombineRepeatedEventCodeBlockNames) + ":  " + string.Join("; ", nonEvents.Select(b => b.GetType().FullName)));
            }
            TES5EventCodeBlock[]         eventBlocks         = blocks.Cast <TES5EventCodeBlock>().ToArray();
            List <TES5FunctionCodeBlock> functions           = new List <TES5FunctionCodeBlock>();
            TES5ObjectCallArguments?     localScopeArguments = null;

            for (int i = 0; i < eventBlocks.Length; i++)
            {
                ITES5CodeBlock    block            = eventBlocks[i];
                TES5FunctionScope newFunctionScope = new TES5FunctionScope(blockType + "_" + (i + 1).ToString());
                foreach (var parameter in block.FunctionScope.GetParameters())
                {
                    newFunctionScope.AddParameter(parameter);
                }

                TES5FunctionCodeBlock function = new TES5FunctionCodeBlock(newFunctionScope, block.CodeScope, TES5VoidType.Instance, isStandalone, false);
                functions.Add(function);
                if (localScopeArguments == null)
                {
                    localScopeArguments = new TES5ObjectCallArguments();
                    foreach (var parameter in block.FunctionScope.GetParameters())
                    {
                        localScopeArguments.Add(TES5ReferenceFactory.CreateReferenceToVariableOrProperty(parameter));
                    }
                }
            }

            if (functions.Any())
            {
                //Create the proxy block.
                ITES5CodeBlock     lastBlock  = blocks.Last();
                TES5EventCodeBlock proxyBlock = TES5BlockFactory.CreateEventCodeBlock(
                    //WTM:  Change:  block was used below, but block is out of scope.  The PHP must have been using the last defined block from above.
                    //WTM:  Change:  PHP called "clone" below, but I'm not sure if this is necessary or would even operate the same in C#.
                    lastBlock.FunctionScope, globalScope);
                foreach (var function in functions)
                {
                    yield return(function);

                    TES5ObjectCall functionCall = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), function.BlockName, localScopeArguments, false// hacky.
                                                                                          );
                    proxyBlock.AddChunk(functionCall);
                }

                yield return(proxyBlock);
            }

            /*
             * //This was not ultimately necessary.
             * IGrouping<string, TES5StateCodeBlock>[] states = blocks.OfType<TES5StateCodeBlock>().ToLookup(b => b.BlockName).ToArray();
             * List<TES5CodeBlock> consolidatedStateCodeBlocks = states.Where(b => b.Count() == 1).SelectMany(b => b.Select(b2 => (TES5CodeBlock)b2).ToArray()).ToList();
             * IGrouping<string, TES5StateCodeBlock>[] repeatedStateCodeBlocks = states.Where(b => b.Count() > 1).ToArray();
             * for (int i = 0; i < repeatedStateCodeBlocks.Length; i++)
             * {
             *  IGrouping<string, TES5StateCodeBlock> groupsWithSameName = repeatedStateCodeBlocks[i];
             *  TES5StateCodeBlock firstGroup = groupsWithSameName.First();
             *  foreach (var otherGroup in groupsWithSameName.Skip(1))
             *  {
             *      foreach (ITES5CodeChunk chunk in otherGroup.CodeScope.CodeChunks)
             *      {
             *          firstGroup.AddChunk(chunk);
             *      }
             *  }
             *  if (firstGroup.CodeBlocks.Blocks.Any())
             *  {
             *      TES5CodeBlock[] reducedBlocks = CombineRepeatedCodeBlockNames(firstGroup.CodeBlocks.Blocks, blockType, isStandalone, globalScope, multipleScriptsScope).ToArray();
             *      firstGroup.CodeBlocks.Blocks.Clear();
             *      firstGroup.CodeBlocks.Blocks.AddRange(reducedBlocks);
             *  }
             *  consolidatedStateCodeBlocks.Add(firstGroup);
             * }
             * foreach(TES5CodeBlock codeBlock in consolidatedStateCodeBlocks)
             * {
             *  yield return codeBlock;
             * }
             */
        }
        public TES5CodeScope Modify(TES4CodeBlock block, TES5BlockList blockList, TES5FunctionScope blockFunctionScope, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            //https://cs.elderscrolls.com/index.php?title=Begin
            //WTM:  Change:  Added:  I reorganized this method and forced each event to account for the first Oblivion parameter.
            bool accountedForParameter = false;

            switch (block.BlockType.ToLower())
            {
            case "gamemode":
            case "scripteffectupdate":
            {
                TES5ObjectCall function = this.objectCallFactory.CreateRegisterForSingleUpdate(globalScope);
                codeScope.AddChunk(function);
                if (globalScope.ScriptHeader.ScriptType.NativeType == TES5BasicType.T_QUEST)
                {
                    TES5EventCodeBlock onInitBlock = TES5BlockFactory.CreateOnInit();
                    onInitBlock.AddChunk(function);
                    blockList.Add(onInitBlock);
                }
                break;
            }

            case "menumode":
            {
                TES5ComparisonExpression isInMenuModeComparisonExpression = GetIsInMenuModeComparisonExpression();
                codeScope             = SetUpBranch(blockFunctionScope, codeScope, isInMenuModeComparisonExpression);
                accountedForParameter = true;        //Skyrim handles menus differently than Oblivion's MenuType.
                break;
            }

            case "onactivate":
            {
                TES5EventCodeBlock onInitBlock = TES5BlockFactory.CreateOnInit();
                TES5ObjectCall     function    = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "BlockActivation");
                onInitBlock.AddChunk(function);
                blockList.Add(onInitBlock);
                //WTM:  Change:  Added:  The following scripts erroneously add a parameter to their OnActivate block:
                //MS11BradonCorpse, SE01WaitingRoomScript, SE02LoveLetterScript, SE08Xeddefen03DoorSCRIPT, SE08Xeddefen05DoorSCRIPT, SE32TombEpitaph01SCRIPT, SEHillofSuicidesSCRIPT, SEXidPuzButton1, SEXidPuzButton2, SEXidPuzButton3, SEXidPuzButton4, SEXidPuzButtonSCRIPT, SEXidPuzHungerSCRIPT, XPEbroccaCrematorySCRIPT
                //But OnActivate does not take a parameter.  I'm trying to use the author's intended parameter instead of just ignoring it.
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akActivateRef", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }


            case "onactorequip":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, TES5LocalVariableParameterMeaning.CONTAINER, globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "onadd":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akNewContainer", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "onalarm":
            {
                //@INCONSISTENCE - We don"t account for CrimeType or Criminal.
                codeScope.AddChunk(this.objectCallFactory.CreateObjectCall(TES5StaticReferenceFactory.Debug, "Trace", new TES5ObjectCallArguments()
                    {
                        new TES5String("This function does not account for OnAlarm's CrimeType or Criminal.")
                    }));
                ITES5Value isAlarmed = TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "IsAlarmed"), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(true));
                codeScope             = SetUpBranch(blockFunctionScope, codeScope, isAlarmed);
                accountedForParameter = true;
                break;
            }

            /*
             * case "onalarm":
             * {
             *
             *  this.skyrimGroupEventName = "onhit";
             *
             *  if (this.eventArgs[1] != 3) {
             *      //Nothing eelse is supported really..
             *      this.omit = true;
             *      break;
             *  }
             *
             *  branch = new TES4ConditionalBranch();
             *  expression = new TES4Expression();
             *  leftConstant = new TES4Constant("akAggressor", "ObjectReference");
             *  //actionConstant        = new TES4Constant(this.eventArgs[1],"Package");
             *  actionConstant = TES4Factories.createReference(this.eventArgs[2], this);
             *
             *  expression.left_side = leftConstant;
             *  expression.right_side = actionConstant;
             *  expression.comparision_operator = TES4Expression.COMPARISION_OPERATOR_EQUAL;
             *
             *  codeBlock = new TES4CodeBlock();
             *  codeBlock.chunks = this.chunks;
             *
             *  branch.ifs[] = array(
             *      "rawExpression" => "SCRIPT_GENERATED",
             *      "expression" => expression,
             *      "codeBlock" => codeBlock
             *  );
             *  this.chunks = new TES4ChunkContainer();
             *  this.chunks.parent = this;
             *  this.chunks.addChunk(branch);
             *
             *  break;
             * }
             */

            case "ondeath":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akKiller", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "ondrop":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akOldContainer", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "onequip":
            case "onunequip":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akActor", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "onhit":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akAggressor", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "onhitwith":
            {
                TES4BlockParameterList?parameterList = block.BlockParameterList;
                if (parameterList != null)
                {
                    TES5LocalScope           localScope          = codeScope.LocalScope;
                    ITES5Referencer          hitWithCriteria     = this.referenceFactory.CreateReadReference(parameterList.Parameters[0].BlockParameter, globalScope, multipleScriptsScope, localScope);
                    TES5SignatureParameter   akSource            = localScope.FunctionScope.GetParameter("akSource");
                    TES5ComparisonExpression hitWithEqualsSource = TES5ExpressionFactory.CreateComparisonExpression(TES5ReferenceFactory.CreateReferenceToVariableOrProperty(akSource), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, hitWithCriteria);
                    TES5CodeScope            newCodeScope        = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope);
                    if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(TES5BasicType.T_AMMO, hitWithCriteria.TES5Type))
                    {
                        newCodeScope.AddChunk(this.objectCallFactory.CreateObjectCall(TES5StaticReferenceFactory.Debug, "Trace", new TES5ObjectCallArguments()
                            {
                                new TES5String("OBScript called OnHitWith using Ammo, but it's unlikely Papyrus will handle it properly.  When arrows are used, " + akSource.Name + " will be a bow.")
                            }));
                    }
                    newCodeScope.AddChunk(new TES5Branch(new TES5SubBranch(hitWithEqualsSource, codeScope)));
                    codeScope = newCodeScope;
                }
                accountedForParameter = true;
                break;
            }

            case "onmagiceffecthit":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akEffect", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "onpackagestart":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akNewPackage", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "onpackagechange":
            case "onpackagedone":
            case "onpackageend":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akOldPackage", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "onsell":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akSeller", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "onstartcombat":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akTarget", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "ontrigger":
            {
                codeScope             = SetUpBranch(block, codeScope, blockFunctionScope, "akActivateRef", globalScope, multipleScriptsScope);
                accountedForParameter = true;
                break;
            }

            case "ontriggeractor":
            {
                TES4BlockParameterList?  parameterList                = block.BlockParameterList;
                TES5LocalScope           localScope                   = codeScope.LocalScope;
                ITES5VariableOrProperty  activator                    = localScope.GetVariableWithMeaning(TES5LocalVariableParameterMeaning.ACTIVATOR);
                TES5LocalVariable        castedToActor                = new TES5LocalVariable("akAsActor", TES5BasicType.T_ACTOR);
                TES5Reference            referenceToCastedVariable    = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(castedToActor);
                TES5Reference            referenceToNonCastedVariable = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(activator);
                TES5ComparisonExpression expression                   = TES5ExpressionFactory.CreateComparisonExpression(referenceToCastedVariable, TES5ComparisonExpressionOperator.OPERATOR_NOT_EQUAL, new TES5None());
                TES5CodeScope            newCodeScope                 = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope);
                newCodeScope.AddVariable(castedToActor);
                newCodeScope.AddChunk(TES5VariableAssignationFactory.CreateAssignation(referenceToCastedVariable, referenceToNonCastedVariable));
                TES5CodeScope outerBranchCode = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope);
                outerBranchCode.LocalScope.CopyVariablesFrom(codeScope.LocalScope);
                if (parameterList != null)
                {
                    ITES5Referencer          targetActor     = this.referenceFactory.CreateReadReference(parameterList.Parameters[0].BlockParameter, globalScope, multipleScriptsScope, localScope);
                    TES5ComparisonExpression interExpression = TES5ExpressionFactory.CreateComparisonExpression(TES5ReferenceFactory.CreateReferenceToVariableOrProperty(activator), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, targetActor);
                    outerBranchCode.AddChunk(new TES5Branch(new TES5SubBranch(interExpression, codeScope)));
                }
                else
                {
                    outerBranchCode.AddChunks(codeScope.CodeChunks);
                }
                newCodeScope.AddChunk(new TES5Branch(new TES5SubBranch(expression, outerBranchCode)));
                codeScope             = newCodeScope;
                accountedForParameter = true;
                break;
            }

            case "onload":
            case "onreset":
            case "ontriggermob":
            case "scripteffectstart":
            case "scripteffectfinish":
            {
                break;
            }

            default:
            {
                throw new InvalidOperationException(block.BlockType + " not found.");
            }
            }
            if (!accountedForParameter)
            {
                TES4BlockParameterList?parameterList = block.BlockParameterList;
                if (parameterList != null && parameterList.Parameters.Any())
                {
                    throw new ConversionException("Parameter not accounted for in " + block.BlockType + ":  " + parameterList.Parameters[0].BlockParameter);
                }
            }
            return(codeScope);
        }
        private TES5CodeScope SetUpBranch(TES4CodeBlock block, TES5CodeScope codeScope, TES5FunctionScope blockFunctionScope, ITES5VariableOrProperty variable, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4BlockParameterList?parameterList = block.BlockParameterList;

            if (parameterList == null)
            {
                return(codeScope);
            }
            TES5Reference            variableReference      = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(variable);
            TES5LocalScope           localScope             = codeScope.LocalScope;
            TES4BlockParameter       firstParameter         = parameterList.Parameters[0];
            ITES5Referencer          firstVariableReference = this.referenceFactory.CreateReadReference(firstParameter.BlockParameter, globalScope, multipleScriptsScope, localScope);
            TES5ComparisonExpression expression             = TES5ExpressionFactory.CreateComparisonExpression(variableReference, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, firstVariableReference);

            return(SetUpBranch(blockFunctionScope, codeScope, expression));
        }
        public void Modify(TES4CodeBlock block, TES5BlockList blockList, TES5EventCodeBlock newBlock, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5FunctionScope blockFunctionScope = newBlock.FunctionScope;

            switch (block.BlockType.ToLower())
            {
            case "gamemode":
            case "scripteffectupdate":
            {
                TES5ObjectCall function = this.objectCallFactory.CreateRegisterForSingleUpdate(globalScope, multipleScriptsScope);
                newBlock.AddChunk(function);
                if (globalScope.ScriptHeader.BasicScriptType == TES5BasicType.T_QUEST)
                {
                    TES5EventCodeBlock onInitBlock = TES5BlockFactory.CreateOnInit();
                    onInitBlock.AddChunk(function);
                    blockList.Add(onInitBlock);
                }
                break;
            }

            case "onactivate":
            {
                TES5EventCodeBlock onInitBlock = TES5BlockFactory.CreateOnInit();
                TES5ObjectCall     function    = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "BlockActivation", multipleScriptsScope);
                onInitBlock.AddChunk(function);
                blockList.Add(onInitBlock);
                break;
            }

            case "onactorequip":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, TES5LocalVariableParameterMeaning.CONTAINER, globalScope, multipleScriptsScope);
                break;
            }

            case "ontriggeractor":
            {
                TES4BlockParameterList   parameterList                = block.BlockParameterList;
                TES5LocalScope           localScope                   = newBlock.CodeScope.LocalScope;
                TES5LocalVariable        activator                    = localScope.GetVariableWithMeaning(TES5LocalVariableParameterMeaning.ACTIVATOR);
                TES5LocalVariable        castedToActor                = new TES5LocalVariable("akAsActor", TES5BasicType.T_ACTOR);
                TES5Reference            referenceToCastedVariable    = TES5ReferenceFactory.CreateReferenceToVariable(castedToActor);
                TES5Reference            referenceToNonCastedVariable = TES5ReferenceFactory.CreateReferenceToVariable(activator);
                TES5ComparisonExpression expression                   = TES5ExpressionFactory.CreateComparisonExpression(referenceToCastedVariable, TES5ComparisonExpressionOperator.OPERATOR_NOT_EQUAL, new TES5None());
                TES5CodeScope            newCodeScope                 = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope);
                newCodeScope.LocalScope.AddVariable(castedToActor);
                newCodeScope.AddChunk(TES5VariableAssignationFactory.CreateAssignation(referenceToCastedVariable, referenceToNonCastedVariable));
                TES5CodeScope outerBranchCode;
                if (parameterList != null)
                {
                    //NOT TESTED
                    List <TES4BlockParameter> parameterListVariableList = parameterList.Parameters;
                    ITES5Referencer           targetActor     = this.referenceFactory.CreateReadReference(parameterListVariableList[0].BlockParameter, globalScope, multipleScriptsScope, localScope);
                    TES5ComparisonExpression  interExpression = TES5ExpressionFactory.CreateComparisonExpression(TES5ReferenceFactory.CreateReferenceToVariable(activator), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, targetActor);
                    //TES5CodeScope interBranchCode = PHPFunction.Deserialize<TES5CodeScope>(PHPFunction.Serialize(newBlock.CodeScope));//WTM:  Change:  Why serialize and then deserialize?
                    TES5CodeScope interBranchCode = newBlock.CodeScope;
                    outerBranchCode = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope);
                    interBranchCode.LocalScope.ParentScope = outerBranchCode.LocalScope;
                    outerBranchCode.AddChunk(new TES5Branch(new TES5SubBranch(interExpression, interBranchCode)));
                }
                else
                {
                    //outerBranchCode = PHPFunction.Deserialize<TES5CodeScope>(PHPFunction.Serialize(newBlock.CodeScope));//WTM:  Change:  Why serialize and then deserialize?
                    outerBranchCode = newBlock.CodeScope;
                    outerBranchCode.LocalScope.ParentScope = newCodeScope.LocalScope;
                }

                newCodeScope.AddChunk(new TES5Branch(new TES5SubBranch(expression, outerBranchCode)));
                newBlock.CodeScope = newCodeScope;
                break;
            }

            case "onadd":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, "akNewContainer", globalScope, multipleScriptsScope);
                break;
            }

            case "ondrop":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, "akOldContainer", globalScope, multipleScriptsScope);
                break;
            }

            case "onpackagestart":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, "akNewPackage", globalScope, multipleScriptsScope);
                break;
            }

            case "onpackagedone":
            case "onpackagechange":
            case "onpackageend":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, "akOldPackage", globalScope, multipleScriptsScope);
                break;
            }

            case "onalarm":
            {
                //@INCONSISTENCE - We don"t account for alarm type.
                TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "IsAlarmed", multipleScriptsScope), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(true));
                SetUpBranch(blockFunctionScope, newBlock, expression);
                break;
            }

            /*
             *
             * case "onalarm":
             * {
             *
             * this.skyrimGroupEventName = "onhit";
             *
             * if (this.eventArgs[1] != 3) {
             *  //Nothing eelse is supported really..
             *  this.omit = true;
             *  break;
             * }
             *
             * branch = new TES4ConditionalBranch();
             * expression = new TES4Expression();
             * leftConstant = new TES4Constant("akAggressor", "ObjectReference");
             * //actionConstant        = new TES4Constant(this.eventArgs[1],"Package");
             * actionConstant = TES4Factories.createReference(this.eventArgs[2], this);
             *
             * expression.left_side = leftConstant;
             * expression.right_side = actionConstant;
             * expression.comparision_operator = TES4Expression.COMPARISION_OPERATOR_EQUAL;
             *
             * codeBlock = new TES4CodeBlock();
             * codeBlock.chunks = this.chunks;
             *
             * branch.ifs[] = array(
             *  "rawExpression" => "SCRIPT_GENERATED",
             *  "expression" => expression,
             *  "codeBlock" => codeBlock
             * );
             * this.chunks = new TES4ChunkContainer();
             * this.chunks.parent = this;
             * this.chunks.addChunk(branch);
             *
             * break;
             * }
             */
            case "onequip":
            case "onunequip":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, "akActor", globalScope, multipleScriptsScope);
                break;
            }
            }
        }
 public static TES5LocalScope CreateRootScope(TES5FunctionScope functionScope)
 {
     return(new TES5LocalScope(functionScope));
 }