/**
  * @param TES5FragmentType $fragmentType
  * @param string $fragmentName
  * @param TES5GlobalScope $globalScope
  * @param TES4CodeChunks $chunks
  * @return TES5FunctionCodeBlock
  */
 public function createFragment(TES5FragmentType $fragmentType, $fragmentName, TES5GlobalScope $globalScope, TES5MultipleScriptsScope $multipleScriptsScope, TES4CodeChunks $chunks)
 {
     $fragmentLocalScope = $this->fragmentLocalScopeFactory->createFromFragmentType($fragmentType);
     $function = new TES5FunctionCodeBlock($fragmentName, new TES5VoidType(), $fragmentLocalScope, $this->codeScopeFactory->createCodeScope($this->fragmentLocalScopeFactory->createRecursiveScope($fragmentLocalScope)));
     foreach ($chunks->getCodeChunks() as $codeChunk) {
         $codeChunks = $this->codeChunkFactory->createCodeChunk($codeChunk, $function->getCodeScope(), $globalScope, $multipleScriptsScope);
         if ($codeChunks !== null) {
             foreach ($codeChunks as $newCodeChunk) {
                 $function->addChunk($newCodeChunk);
             }
         }
     }
     return $function;
 }
 /**
  * @param TES4SubBranch $branch
  * @param TES5CodeScope $outerCodeScope
  * @param TES5GlobalScope $globalScope
  * @return TES5SubBranch
  */
 private function convertSubBranch(TES4SubBranch $branch, TES5CodeScope $outerCodeScope, \Ormin\OBSLexicalParser\TES5\AST\Scope\TES5GlobalScope $globalScope, TES5MultipleScriptsScope $multipleScriptsScope)
 {
     $outerLocalScope = $outerCodeScope->getLocalScope();
     $expression = $this->valueFactory->createValue($branch->getExpression(), $outerCodeScope, $globalScope, $multipleScriptsScope);
     $newScope = $this->localScopeFactory->createRecursiveScope($outerLocalScope);
     $newCodeScope = $this->codeScopeFactory->createCodeScope($newScope);
     $branchChunks = $branch->getCodeChunks();
     if ($branchChunks !== null) {
         foreach ($branchChunks->getCodeChunks() as $codeChunk) {
             $codeChunks = $this->codeChunkFactory->createCodeChunk($codeChunk, $newCodeScope, $globalScope, $multipleScriptsScope);
             if ($codeChunks !== null) {
                 foreach ($codeChunks as $newCodeChunk) {
                     $newCodeScope->add($newCodeChunk);
                 }
             }
         }
     }
     return new TES5SubBranch($expression, $newCodeScope);
 }
 /**
  * @param TES5MultipleScriptsScope $multipleScriptsScope
  * @param TES5GlobalScope $globalScope
  * @param TES4CodeBlock $block
  * @return TES5EventBlockList
  */
 public function createBlock(TES5MultipleScriptsScope $multipleScriptsScope, TES5GlobalScope $globalScope, TES4CodeBlock $block)
 {
     $blockList = new TES5EventBlockList();
     $blockType = $block->getBlockType();
     if (strtolower($blockType) == "menumode") {
         return $blockList;
     }
     $newBlockType = $this->mapBlockType($blockType);
     $blockLocalScope = $this->blockLocalScopeFactory->createFromBlockType($newBlockType, $globalScope);
     $newBlock = new TES5EventCodeBlock($newBlockType, $blockLocalScope, $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope)));
     if ($block->getChunks() !== null) {
         foreach ($block->getChunks()->getCodeChunks() as $codeChunk) {
             $codeChunks = $this->codeChunkFactory->createCodeChunk($codeChunk, $newBlock->getCodeScope(), $globalScope, $multipleScriptsScope);
             if ($codeChunks !== null) {
                 foreach ($codeChunks as $newCodeChunk) {
                     $newBlock->addChunk($newCodeChunk);
                 }
             }
         }
         $this->changesPass->modify($block, $blockList, $newBlock, $globalScope, $multipleScriptsScope);
         $blockList->add($newBlock);
     }
     return $blockList;
 }
 /**
  * @param TES4CodeBlock $block
  * @param TES5EventBlockList $blockList
  * @param TES5EventCodeBlock $newBlock
  * @param TES5MultipleScriptsScope $multipleScriptsScope
  * @param TES5GlobalScope $globalScope
  */
 public function modify(TES4CodeBlock $block, TES5EventBlockList $blockList, TES5EventCodeBlock $newBlock, TES5GlobalScope $globalScope, TES5MultipleScriptsScope $multipleScriptsScope)
 {
     $blockLocalScope = $newBlock->getLocalScope();
     switch (strtolower($block->getBlockType())) {
         case "gamemode":
         case 'scripteffectupdate':
             $onInitLocalScope = $this->blockLocalScopeFactory->createFromBlockType("OnInit", $globalScope);
             $newInitBlock = new TES5EventCodeBlock("OnInit", $onInitLocalScope, $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($onInitLocalScope)));
             $args = new TES5ObjectCallArguments();
             $args->add(new TES5Float(self::ON_UPDATE_TICK));
             $function = $this->valueFactory->createObjectCall($this->referenceFactory->createReferenceToSelf($globalScope), "RegisterForUpdate", $multipleScriptsScope, $args);
             $newInitBlock->addChunk($function);
             $blockList->add($newInitBlock);
             break;
         case "onactivate":
             $onInitLocalScope = $this->blockLocalScopeFactory->createFromBlockType("OnInit", $globalScope);
             $newInitBlock = new TES5EventCodeBlock("OnInit", $onInitLocalScope, $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($onInitLocalScope)));
             $function = $this->valueFactory->createObjectCall($this->referenceFactory->createReferenceToSelf($globalScope), "BlockActivation", $multipleScriptsScope);
             $newInitBlock->addChunk($function);
             $blockList->add($newInitBlock);
             break;
         case 'onactorequip':
             $parameterList = $block->getBlockParameterList();
             if ($parameterList == null) {
                 break;
             }
             $parameterList = $parameterList->getVariableList();
             $tesEquippedTarget = $parameterList[0];
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
             $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->findVariableWithMeaning(TES5LocalVariableParameterMeaning::CONTAINER())), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer);
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case "ontriggeractor":
             $parameterList = $block->getBlockParameterList();
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $activator = $localScope->findVariableWithMeaning(TES5LocalVariableParameterMeaning::ACTIVATOR());
             $castedToActor = new TES5LocalVariable("akAsActor", TES5BasicType::T_ACTOR());
             $referenceToCastedVariable = $this->referenceFactory->createReferenceToVariable($castedToActor);
             $referenceToNonCastedVariable = $this->referenceFactory->createReferenceToVariable($activator);
             $expression = $this->expressionFactory->createArithmeticExpression($referenceToCastedVariable, TES5ArithmeticExpressionOperator::OPERATOR_NOT_EQUAL(), new TES5None());
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $newCodeScope->getLocalScope()->addVariable($castedToActor);
             $newCodeScope->add($this->assignationFactory->createAssignation($referenceToCastedVariable, $referenceToNonCastedVariable));
             if ($parameterList !== null) {
                 //NOT TESTED
                 $parameterList = $parameterList->getVariableList();
                 $targetActor = $this->valueFactory->createReadReference($parameterList[0]->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
                 $interExpression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($activator), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $targetActor);
                 $interBranchCode = unserialize(serialize($newBlock->getCodeScope()));
                 $outerBranchCode = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($newCodeScope->getLocalScope()));
                 $interBranchCode->getLocalScope()->setParentScope($outerBranchCode->getLocalScope());
                 $outerBranchCode->add(new TES5Branch(new TES5SubBranch($interExpression, $interBranchCode)));
             } else {
                 $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
                 $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             }
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case 'onadd':
             $parameterList = $block->getBlockParameterList();
             if ($parameterList == null) {
                 break;
             }
             $parameterList = $parameterList->getVariableList();
             $tesEquippedTarget = $parameterList[0];
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
             $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akNewContainer")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer);
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case 'ondrop':
             $parameterList = $block->getBlockParameterList();
             if ($parameterList == null) {
                 break;
             }
             $parameterList = $parameterList->getVariableList();
             $tesEquippedTarget = $parameterList[0];
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
             $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akOldContainer")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer);
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case 'onpackagestart':
             $parameterList = $block->getBlockParameterList();
             if ($parameterList == null) {
                 break;
             }
             $parameterList = $parameterList->getVariableList();
             $tesEquippedTarget = $parameterList[0];
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
             $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akNewPackage")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer);
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case 'onpackagedone':
         case 'onpackagechange':
         case 'onpackageend':
             $parameterList = $block->getBlockParameterList()->getVariableList();
             $tesEquippedTarget = $parameterList[0];
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
             $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akOldPackage")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer);
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case 'onalarm':
             //@INCONSISTENCE - We don't account for alarm type.
             $expression = $this->expressionFactory->createArithmeticExpression($this->valueFactory->createObjectCall($this->referenceFactory->createReferenceToSelf($globalScope), "IsAlarmed", $multipleScriptsScope), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), new TES5Bool(true));
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             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;
                     }
             */
     }
 }