void handleMouseMotion() { if (_underMousePlant) { Vector3 pos = Utility.GetMouseWorldPos(); Vector3 plantPos = pos /*+(Vector3.up*0.3f)*/; plantPos.y -= 0.3f; _underMousePlant.transform.position = plantPos; if (StageMap.IsPointInMap(plantPos)) { StageMap.GetRowCol(plantPos, out _row, out _col); if (_underMousePlantGrow.CanGrowInMap(_row, _col)) { _transparentPlant.transform.position = StageMap.PlantPosByRowCol(_row, _col); } else { _col = _row = -1; _transparentPlant.transform.position = new Vector3(1000, 1000, 0); } } else { _col = _row = -1; _transparentPlant.transform.position = new Vector3(1000, 1000, 0); } } }
IEnumerator Explode() { yield return(new WaitForSeconds(delayTime)); GameObject newEffect = Instantiate(effect); newEffect.transform.position = transform.position + effectOffset; newEffect.GetComponent <SpriteRenderer>().sortingOrder = transform.Find("plant").GetComponent <SpriteRenderer>().sortingOrder + 1; Destroy(newEffect, 1.5f); SearchZombie search = GetComponent <SearchZombie>(); foreach (GameObject zombie in search.SearchZombiesInCol()) { zombie.GetComponent <ZombieHealthy>().BoomDie(); } AudioManager.GetInstance().PlaySound(explodeSound); GetComponent <PlantHealthy>().Die(); // Create hole GameObject tempPlant = Instantiate(hole); tempPlant.transform.position = StageMap.GetPlantPos(grow.row, grow.col); tempPlant.GetComponent <PlantGrow>().grow(grow.row, grow.col); }
IEnumerator Explode() { yield return(new WaitForSeconds(delayTime)); GameObject newEffect = Instantiate(effect); newEffect.transform.position = new Vector3(1.8f, transform.position.y + 0.5f, 0); newEffect.GetComponent <SpriteRenderer>().sortingOrder = transform.Find("plant").GetComponent <SpriteRenderer>().sortingOrder + 1; Destroy(newEffect, 1.2f); GameModel model = GameModel.GetInstance(); int row = GetComponent <PlantGrow>().row; object[] zombies = model.zombieList[row].ToArray(); foreach (GameObject zombie in zombies) { zombie.GetComponent <ZombieHealthy>().BoomDie(); } AudioManager.GetInstance().PlaySound(explodeSound); GetComponent <PlantHealthy>().Die(); // Create hole GameObject tempPlant = Instantiate(hole); tempPlant.transform.position = StageMap.GetPlantPos(grow.row, grow.col); tempPlant.GetComponent <PlantGrow>().grow(grow.row, grow.col); }
void CreatOneZombie(ZombieType type) { GameObject zombie = null; switch (type) { case ZombieType.Zombie1: zombie = Instantiate(zombie1); break; case ZombieType.ConeHeadZombie: zombie = Instantiate(ConeheadZombie); break; case ZombieType.BucketHeadZombie: zombie = Instantiate(BucketheadZombie); break; } int row = Random.Range(0, StageMap.ROW_MAX); zombie.transform.position = StageMap.SetZombiePos(row); zombie.GetComponent <ZombieMove>().row = row; zombie.GetComponent <SpriteDisplay>().SetOrderByRow(row); model.zombieList[row].Add(zombie); }
void HandleMouseMoveForShovel() { if (shovel) { Vector3 pos = Utility.GetMouseWorldPos(); Vector3 shovelPos = pos; shovelPos.x += 0.1f; shovelPos.y += 0.1f; shovel.transform.position = shovelPos; if (StageMap.IsPointInMap(pos)) { int row, col; StageMap.GetRowAndCol(pos, out row, out col); GameObject plant = GameModel.GetInstance().map[row, col]; if (selectedPlant != plant) { if (selectedPlant) { selectedPlant.GetComponent <SpriteDisplay>().SetAlpha(1f); } if (plant && plant.tag != "UnableSell") { selectedPlant = plant; selectedPlant.GetComponent <SpriteDisplay>().SetAlpha(0.6f); } else { selectedPlant = null; } } } } }
void HandleMouseMoveForPlant() { if (selectedPlant) { Vector3 pos = Utility.GetMouseWorldPos(); Vector3 plantPos = pos; plantPos.y -= 0.3f; selectedPlant.transform.position = plantPos; if (StageMap.IsPointInMap(pos)) { StageMap.GetRowAndCol(pos, out row, out col); if (tempPlant.GetComponent <PlantGrow>().canGrowInMap(row, col)) { tempPlant.transform.position = StageMap.GetPlantPos(row, col); tempPlant.GetComponent <SpriteDisplay>().SetOrderByRow(row); } else { col = row = -1; tempPlant.transform.position = new Vector3(1000, 1000, 0); } } else { col = row = -1; tempPlant.transform.position = new Vector3(1000, 1000, 0); } } }
public void ErrorEffectOn(int x, int y) { Vector3 touchPos = StageMap.GetTouchPos(x, y); GameObject newEffect = Instantiate(effectLevel[0]); Vector3 effectOffset = new Vector3(0f, -0.1f, 0f); newEffect.transform.position = touchPos + effectOffset; model.levelEffect[x, y] = newEffect; //Destroy(newEffect, 2f); }
void updatePlantsOnMap() { for (int i = 0; i < StageMap.MAP_MAX; i++) { int x = i / StageMap.COL_MAX; int y = i % StageMap.COL_MAX; if (stackSensing[i] != 0 && model.map[x, y] == null && !hasPlant[i]) { if (model.sun - 150 >= 0 || (stackSensing[i] == 12 && model.sun - 50 >= 0)) { if (stackSensing[i] == 12) { model.sun -= 50; } else { model.sun -= 150; } tempPlant = Instantiate(plantsForPlayer[stackSensing[i] - 1]); tempPlant.transform.position = StageMap.GetPlantPos(i / StageMap.COL_MAX, i % StageMap.COL_MAX); tempPlant.GetComponent <PlantGrow>().grow(x, y); AudioManager.GetInstance().PlaySound(plantGrow); tempPlant = null; hasPlant[i] = true; } else { money.SetTrigger("nomoney"); } } else if (stackSensing[i] == 0 && hasPlant[i] && !model.holeMap[x, y]) { GameObject tempPlant = model.map[x, y]; tempPlant.GetComponent <PlantHealthy>().Die(); hasPlant[i] = false; } else if (stackSensing[i] == 0 && hasPlant[i] && model.holeMap[x, y]) { GameObject tempPlant = model.map[x, y]; model.map[x, y] = null; Destroy(tempPlant); hasPlant[i] = false; } } }
void CreateOneZombie(ZombieType type) { GameObject zombie; switch (type) { case ZombieType.Zombie1: zombie = Instantiate(Zombie1); break; case ZombieType.Zombie2: zombie = Instantiate(Zombie2); break; case ZombieType.FlagZombie: zombie = Instantiate(FlagZombie); break; case ZombieType.ConeheadZombie: zombie = Instantiate(ConeheadZombie); break; case ZombieType.BucketheadZombie: zombie = Instantiate(BucketheadZombie); break; case ZombieType.PoleVaultingZombie: zombie = Instantiate(PoleVaultingZombie); break; case ZombieType.NewspaperZombie: zombie = Instantiate(NewspaperZombie); break; default: throw new System.Exception("Wrong zombie type"); } int row = Random.Range(0, StageMap.ROW_MAX - 1); zombie.transform.position = StageMap.GetZombiePos(row); zombie.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f); zombie.GetComponent <ZombieMove>().row = row; zombie.GetComponent <SpriteDisplay>().SetOrderByRow(row); model.zombieList[row].Add(zombie); }
void ProduceSun() { if (moneycount <= 0) { //int x = Random.Range(0, StageMap.ROW_MAX); //int y = Random.Range(0, StageMap.COL_MAX); //int y = Random.Range(4, 7); int[] x_array = new int[5] { 0, 2, 3, 1, 4 }; int[] y_array = new int[5] { 2, 8, 3, 0, 5 }; if (i < 5) { int x = x_array[i]; int y = y_array[i]; if (model.sunMap[x, y] == null) { GameObject sun = Instantiate(sunPrefab); sun.transform.position = StageMap.GetSunPos(x, y); ScaleUp scaleup = sun.AddComponent <ScaleUp>(); scaleup.Begin(); model.sunMap[x, y] = sun; } i++; } //int x = Random.Range(0, StageMap.ROW_MAX); //int y = Random.Range(0, StageMap.COL_MAX); //if (model.sunMap[x, y] == null) //{ // GameObject sun = Instantiate(sunPrefab); // sun.transform.position = StageMap.GetSunPos(x, y); // ScaleUp scaleup = sun.AddComponent<ScaleUp>(); // scaleup.Begin(); // model.sunMap[x, y] = sun; //} } }
void handleMouseMoveForShovel() { if (!shovel) { return; } Vector3 pos = Utility.GetMouseWorldPos(); Vector3 shovelPos = pos; shovelPos.x += 0.1f; shovelPos.y += 0.1f; Vector2 localPos; RectTransformUtility.ScreenPointToLocalPointInRectangle(shovelBg.transform as RectTransform, Input.mousePosition, Camera.main, out localPos); shovel.transform.localPosition = localPos; if (!StageMap.IsPointInMap(pos)) { return; } int row, col; StageMap.GetRowCol(pos, out row, out col); GameObject plant = GameModel.GetInstance().PlantsInMap[row, col]; if (selectedPlant == plant) { return; //铁铲从当前指向的植物 到了其他地方(有植物或没植物) } if (selectedPlant) //如果原来有指向的植物 { selectedPlant.GetComponent <PlantSpriteDisplay>().SetAlpha(1f); } if (plant)//如果指向了新植物 { selectedPlant = plant; selectedPlant.GetComponent <PlantSpriteDisplay>().SetAlpha(0.6f); } else { selectedPlant = null; } }
void updateErrorOnMap() { for (int i = 0; i < ErrorOnMap.Length; i++) { if (ErrorOnMap[i] == null) { ErrorTypesOnMap[i] = 0; } if (ErrorTypesOnMap[i] == 0 && stackerror[i] == 0 && !resetr[i]) { resetr[i] = true; } if (ErrorTypesOnMap[i] != stackerror[i]) { if (stackerror[i] == 0) { ErrorOnMap[i].GetComponent <errordie>().Die(); ErrorTypesOnMap[i] = stackerror[i]; resetr[i] = true; } else { if (ErrorTypesOnMap[i] != 0) { ErrorOnMap[i].GetComponent <errordie>().Die(); resetr[i] = true; } if (resetr[i]) { tempError = Instantiate(serror[stackerror[i] - 1]); tempError.transform.position = StageMap.GetErrorIconPos(i / StageMap.COL_MAX, i % StageMap.COL_MAX); tempError.GetComponent <errordie>().grow(i / StageMap.COL_MAX, i % StageMap.COL_MAX); ErrorOnMap[i] = tempError; tempError = null; ErrorTypesOnMap[i] = stackerror[i]; resetr[i] = false; } } } } }
public void LoadSelectedStage() { if (selectedIndex == -1) { Debug.Log("please select a stage"); return; } var fileContent = File.ReadAllText(stagePaths[selectedIndex]); map = StageBuilder.Instance.LoadStageFromJsonInGame(fileContent.ToString()); player.StartPosition = (map.PlayerSpawns != null || map.PlayerSpawns.Count == 0) ? Vector3.zero + Vector3.up * 3: map.PlayerSpawns[0].transform.position + (Vector3.up); map.RepositionToInGame(); player.ResetPosition(); }
void HandleMouseDownForPlant() { if (Input.GetMouseButtonDown(0)) { Collider2D collider = Physics2D.OverlapPoint(Utility.GetMouseWorldPos()); if (collider != null) { CancelSelectdCard(); if (collider.gameObject.tag == "Card") { collider.gameObject.SendMessage("OnSelect"); AudioManager.GetInstance().PlaySound(seedLift); } } else if (selectedPlant) { if (row != -1) { selectedPlant.transform.position = StageMap.GetPlantPos(row, col); selectedPlant.GetComponent <PlantGrow>().grow(row, col); AudioManager.GetInstance().PlaySound(plantGrow); selectedPlant = null; Destroy(tempPlant); tempPlant = null; selectedCard.Select(); selectedCard = null; } else { CancelSelectdCard(); } } } if (Input.GetMouseButtonDown(1)) { CancelSelectdCard(); } }
//创建僵尸 void CreateOneZombie(ZombieType type) { GameObject zombie = null; switch (type) { case ZombieType.Zombie1: zombie = Instantiate(zombie1); break; default: break; } int row = Random.Range(0, StageMap.MaxRow); zombie.transform.position = StageMap.ZombiePosByRow(row); zombie.GetComponent <ZombieMove>().Row = row; zombie.GetComponent <ZombieSpriteDisplay>().SetOrderByRow(row); _model.zombieList[row].Add(zombie); }
public void HoldLevel(int x, int y, int level) { if (level >= 0) { Vector3 touchPos = StageMap.GetTouchPos(x, y); GameObject newEffect = Instantiate(effectLevel[level]); Vector3 effectOffset; if (level == 0) { effectOffset = new Vector3(0f, -0.1f, 0f); } else { effectOffset = new Vector3(1f, 0f, 0f); } newEffect.transform.position = touchPos + effectOffset; model.levelEffect[x, y] = newEffect; } }
public override void Execute() { if (!PreExecutionChecks(false, true, false, false)) { return; } Build build = new Build(Build.DEFAULT_BUILD_PATH); BuildTarget buildTarget = BuildTargetFactory.Construct(BuildTargetFactory.QFName, build); bool preprocessed; Dictionary <int, List <int> > originalStageMap = StageMapFromMAPBuilder.BuildStageMapDictionary(buildTarget, "QF_FGC01Rats_01035713", out preprocessed); StageMap stageMap = new StageMap(originalStageMap.ToDictionary(m => m.Key, m => m.Value.ToList()), preprocessed);//Copy dictionary StringBuilder output = new StringBuilder(StageMapToMAPBuilder.GetContents(stageMap, originalStageMap)); output.Append("Mapping index print"); foreach (var kvp in stageMap.MappedTargetsIndex) { var originalTargetIndex = kvp.Key; var mappedTargetIndexes = kvp.Value; output.AppendLine(); output.Append(originalTargetIndex + " - " + string.Join(" ", mappedTargetIndexes)); } string outputString = output.ToString(); Console.WriteLine(outputString); const string fgc01RatsResultFromPHP = @"10 - 0 0 0 1 10 - 0 0 0 1 0 0 0 0 0 0 20 - 1 0 0 0 20 - 1 0 0 0 0 0 0 0 0 0 30 - 0 0 0 1 30 - 0 0 0 0 1 0 0 0 0 0 40 - 0 0 1 0 40 - 0 0 1 0 0 0 0 0 0 0 50 - 0 0 1 0 50 - 0 0 1 0 0 0 0 0 0 0 55 - 0 0 0 1 55 - 0 0 0 0 0 1 0 0 0 0 60 - 1 0 0 0 60 - 0 0 0 0 0 0 1 0 0 0 65 - 0 0 0 1 65 - 0 0 0 0 0 0 0 1 0 0 70 - 0 1 0 0 70 - 0 1 0 0 0 0 0 0 0 0 80 - 0 1 0 0 80 - 0 1 0 0 0 0 0 0 0 0 90 - 0 0 0 1 90 - 0 0 0 0 0 0 0 0 1 0 100 - 0 0 0 0 100 - 0 0 0 0 0 0 0 0 0 0 105 - 0 1 0 0 105 - 0 0 0 0 0 0 0 0 0 1 110 - 0 0 0 0 110 - 0 0 0 0 0 0 0 0 0 0 200 - 0 0 0 0 200 - 0 0 0 0 0 0 0 0 0 0 Mapping index print 3 - 4 5 7 8 0 - 6 1 - 9"; bool match = fgc01RatsResultFromPHP.Replace("\r\n", "\n") == outputString.Replace("\r\n", "\n"); Console.WriteLine("Output " + (match ? "matched" : "did not match") + " the output of the PHP version."); }
public override void Execute() { if (!PreExecutionChecks(false, false, false, false)) { return; } Build build = new Build(Build.DEFAULT_BUILD_PATH); Dictionary <int, List <int> > originalStageMap; using (BuildLogServices buildLogServices = new BuildLogServices(build)) { BuildTarget buildTarget = BuildTargetFactory.Get(BuildTarget.BUILD_TARGET_QF, build, buildLogServices); originalStageMap = QFFragmentFactory.BuildStageMapDictionary(buildTarget, "QF_FGC01Rats_01035713"); } StageMap stageMap = new StageMap(originalStageMap.ToDictionary(m => m.Key, m => m.Value.ToList()));//Copy dictionary StringBuilder output = new StringBuilder(); foreach (var stageId in stageMap.StageIDs) { output.AppendLine(stageId.ToString() + " - " + string.Join(" ", originalStageMap[stageId])); output.Append(stageId.ToString() + " -"); List <int> map = stageMap.GetStageTargetsMap(stageId); foreach (var val in map) { output.Append(" " + val); } output.AppendLine(); } output.Append("Mapping index print"); foreach (var kvp in stageMap.MappedTargetsIndex) { var originalTargetIndex = kvp.Key; var mappedTargetIndexes = kvp.Value; output.AppendLine(); output.Append(originalTargetIndex + " - " + string.Join(" ", mappedTargetIndexes)); } string outputString = output.ToString(); Console.WriteLine(outputString); const string fgc01RatsResultFromPHP = @"10 - 0 0 0 1 10 - 0 0 0 1 0 0 0 0 0 0 20 - 1 0 0 0 20 - 1 0 0 0 0 0 0 0 0 0 30 - 0 0 0 1 30 - 0 0 0 0 1 0 0 0 0 0 40 - 0 0 1 0 40 - 0 0 1 0 0 0 0 0 0 0 50 - 0 0 1 0 50 - 0 0 1 0 0 0 0 0 0 0 55 - 0 0 0 1 55 - 0 0 0 0 0 1 0 0 0 0 60 - 1 0 0 0 60 - 0 0 0 0 0 0 1 0 0 0 65 - 0 0 0 1 65 - 0 0 0 0 0 0 0 1 0 0 70 - 0 1 0 0 70 - 0 1 0 0 0 0 0 0 0 0 80 - 0 1 0 0 80 - 0 1 0 0 0 0 0 0 0 0 90 - 0 0 0 1 90 - 0 0 0 0 0 0 0 0 1 0 100 - 0 0 0 0 100 - 0 0 0 0 0 0 0 0 0 0 105 - 0 1 0 0 105 - 0 0 0 0 0 0 0 0 0 1 110 - 0 0 0 0 110 - 0 0 0 0 0 0 0 0 0 0 200 - 0 0 0 0 200 - 0 0 0 0 0 0 0 0 0 0 Mapping index print 3 - 4 5 7 8 0 - 6 1 - 9"; bool match = fgc01RatsResultFromPHP.Replace("\r\n", "\n") == outputString.Replace("\r\n", "\n"); Console.WriteLine("Output " + (match ? "matched" : "did not match") + " the output of the PHP version."); }
/* * Joins N QF subfragments into one QF fragment that can be properly binded into Skyrim VM * @throws ConversionException */ public TES5Target JoinQFFragments(BuildTarget target, string resultingFragmentName, List <QuestStageScript> subfragmentsTrees) { StageMap stageMap = BuildStageMap(target, resultingFragmentName); /* * We need script fragment for objective handling for each stage, so when parsing the script fragments, * we"ll be marking them there, and intersecting this with stage. * This will give us an array of stages which don"t have script fragment, but will need it anyways * for objective handling. */ TES5ScriptHeader resultingScriptHeader = new TES5ScriptHeader(resultingFragmentName, TES5BasicType.T_QUEST, "", true); TES5BlockList resultingBlockList = new TES5BlockList(); TES5GlobalScope resultingGlobalScope = new TES5GlobalScope(resultingScriptHeader); /* * Add ReferenceAlias"es * At some point, we might port the conversion so it doesn"t use the directly injected property, * but instead has a map to aliases and we"ll map accordingly and have references point to aliases instead */ string sourcePath = target.GetSourceFromPath(resultingFragmentName); string scriptName = Path.GetFileNameWithoutExtension(sourcePath); string aliasesFile = Path.Combine(Path.GetDirectoryName(sourcePath), scriptName + ".aliases"); string[] aliasesLines = File.ReadAllLines(aliasesFile); Dictionary <string, bool> aliasesDeclared = new Dictionary <string, bool>(); foreach (var alias in aliasesLines) { string trimmedAlias = alias.Trim(); if (trimmedAlias == "") { continue; } try { aliasesDeclared.Add(trimmedAlias, true); } catch (ArgumentException) { continue; } resultingGlobalScope.AddProperty(new TES5Property(trimmedAlias, TES5BasicType.T_REFERENCEALIAS, trimmedAlias)); } Dictionary <int, bool> implementedStages = new Dictionary <int, bool>(); Dictionary <string, bool> propertiesNamesDeclared = new Dictionary <string, bool>(); foreach (var subfragment in subfragmentsTrees) { TES5Target subfragmentsTree = subfragment.Script; TES5Script subfragmentScript = subfragmentsTree.Script; TES5GlobalScope subfragmentGlobalScope = subfragmentScript.GlobalScope; foreach (TES5Property subfragmentProperty in subfragmentGlobalScope.Properties) { /* * Move over the properties to the new global scope */ string propertyName; if (propertiesNamesDeclared.ContainsKey(subfragmentProperty.Name)) { propertyName = GeneratePropertyName(subfragmentScript.ScriptHeader, subfragmentProperty); subfragmentProperty.Rename(propertyName); } else { propertyName = subfragmentProperty.Name; } propertiesNamesDeclared.Add(propertyName, true); resultingGlobalScope.AddProperty(subfragmentProperty); //WTM: Note: See QF_FGD03Viranus_0102d154. Since ViranusDontonREF is present in multiple of the original fragments, //ViranusDontonREF gets renamed by the above. So multiple ViranusDontonREF variables are output. //Below I tried not renaming, assuming instead that variables with matching names and types within a set of fragments were intended to be the same variable. //It had OK results, but I'm leaving it commented for now. /*string propertyNameWithSuffix = subfragmentProperty.PropertyNameWithSuffix; * TES5Property existingProperty = resultingGlobalScope.Properties.Where(p => p.PropertyNameWithSuffix == propertyNameWithSuffix).FirstOrDefault(); * if (existingProperty != null && TES5InheritanceGraphAnalyzer.isExtending(subfragmentProperty.PropertyType, existingProperty.PropertyType)) * { * existingProperty.PropertyType = subfragmentProperty.PropertyType; * } * else * { * bool add = true; * if (existingProperty != null) * { * if (TES5InheritanceGraphAnalyzer.isExtending(existingProperty.PropertyType, subfragmentProperty.PropertyType)) * { * add = false; * } * else * { * string generatedPropertyName = generatePropertyName(subfragmentScript.ScriptHeader, subfragmentProperty, i); * subfragmentProperty.Rename(generatedPropertyName); * } * } * if (add) * { * resultingGlobalScope.Add(subfragmentProperty); * } * }*/ } List <ITES5CodeBlock> subfragmentBlocks = subfragmentScript.BlockList.Blocks; if (subfragmentBlocks.Count != 1) { throw new ConversionException("Wrong QF fragment, actual function count: " + subfragmentBlocks.Count + ".."); } ITES5CodeBlock subfragmentBlock = subfragmentBlocks[0]; if (subfragmentBlock.FunctionScope.BlockName != "Fragment_0") { throw new ConversionException("Wrong QF fragment funcname, actual function name: " + subfragmentBlock.FunctionScope.BlockName + ".."); } string newFragmentFunctionName = "Fragment_" + subfragment.Stage.ToString(); if (subfragment.LogIndex != 0) { newFragmentFunctionName += "_" + subfragment.LogIndex; } subfragmentBlock.FunctionScope.Rename(newFragmentFunctionName); var objectiveCodeChunks = this.objectiveHandlingFactory.GenerateObjectiveHandling(subfragmentBlock, resultingGlobalScope, stageMap.GetStageTargetsMap(subfragment.Stage)); foreach (var newCodeChunk in objectiveCodeChunks) { subfragmentBlock.AddChunk(newCodeChunk); } resultingBlockList.Add(subfragmentBlock); implementedStages[subfragment.Stage] = true; } /* * Diff to find stages which we still need to mark */ int[] nonDoneStages = stageMap.StageIDs.Where(stageID => !implementedStages.ContainsKey(stageID)).ToArray(); foreach (int nonDoneStage in nonDoneStages) { TES5FunctionCodeBlock fragment = this.objectiveHandlingFactory.CreateEnclosedFragment(resultingGlobalScope, nonDoneStage, stageMap.GetStageTargetsMap(nonDoneStage)); resultingBlockList.Add(fragment); } this.mappedTargetsLogService.WriteScriptName(resultingFragmentName); foreach (var kvp in stageMap.MappedTargetsIndex) { var originalTargetIndex = kvp.Key; var mappedTargetIndexes = kvp.Value; this.mappedTargetsLogService.WriteLine(originalTargetIndex, mappedTargetIndexes); } TES5Script resultingTree = new TES5Script(resultingGlobalScope, resultingBlockList); string outputPath = target.GetTranspileToPath(resultingFragmentName); return(new TES5Target(resultingTree, outputPath)); }
/* * Joins N QF subfragments into one QF fragment that can be properly binded into Skyrim VM * @throws ConversionException */ public TES5Target JoinQFFragments(IBuildTarget target, string resultingFragmentName, List <QuestStageScript> subfragmentsTrees) { int tes4FormID = GetTES4FormID(resultingFragmentName); StageMap stageMap = StageMapBuilder.Build(target, resultingFragmentName, esmAnalyzer, tes4FormID); /* * We need script fragment for objective handling for each stage, so when parsing the script fragments, * we"ll be marking them there, and intersecting this with stage. * This will give us an array of stages which don"t have script fragment, but will need it anyways * for objective handling. */ TES5ScriptHeader resultingScriptHeader = TES5ScriptHeaderFactory.GetFromCacheOrConstructByBasicType(resultingFragmentName, TES5BasicType.T_QUEST, TES5TypeFactory.TES4_Prefix, true); TES5GlobalScope resultingGlobalScope = new TES5GlobalScope(resultingScriptHeader); string[] referenceAliases = ReferenceAliasBuilder.Build(target, resultingFragmentName, esmAnalyzer, tes4FormID).ToArray(); foreach (string propertyName in referenceAliases) { resultingGlobalScope.AddProperty(TES5PropertyFactory.ConstructWithoutFormID(propertyName, TES5BasicType.T_REFERENCEALIAS, propertyName)); } List <QuestStageBlock> questStageBlocks = new List <QuestStageBlock>(); HashSet <int> implementedStages = new HashSet <int>(); HashSet <string> propertiesNamesDeclared = new HashSet <string>(); foreach (var subfragment in subfragmentsTrees) { TES5Target subfragmentsTree = subfragment.Script; TES5Script subfragmentScript = subfragmentsTree.Script; TES5GlobalScope subfragmentGlobalScope = subfragmentScript.GlobalScope; foreach (TES5Property subfragmentProperty in subfragmentGlobalScope.Properties) { /* * Move over the properties to the new global scope */ if (propertiesNamesDeclared.Add(subfragmentProperty.Name)) { resultingGlobalScope.AddProperty(subfragmentProperty); } else { if (subfragmentProperty.IsPlayerRef) { continue; } //WTM: Change: I don't think renaming these properties actually helps anything. /* * string propertyName = GeneratePropertyName(subfragmentScript.ScriptHeader, subfragmentProperty); * subfragmentProperty.Rename(propertyName); * if (!propertiesNamesDeclared.Add(subfragmentProperty.Name)) * { * throw new ConversionException(nameof(propertiesNamesDeclared) + " already contained property " + subfragmentProperty.Name + "."); * } */ //WTM: Change: I'm trying to unify properties and include extended type declarations. TES5Property existingProperty = resultingGlobalScope.GetPropertyByName(subfragmentProperty.Name); if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(existingProperty.TES5Type, subfragmentProperty.TES5Type)) { continue; } if (TES5InheritanceGraphAnalyzer.IsExtending(subfragmentProperty.TES5Type, existingProperty.TES5Type)) { existingProperty.TES5Type = subfragmentProperty.TES5Type; continue; } if (TES5InheritanceGraphAnalyzer.IsExtending(existingProperty.TES5Type, subfragmentProperty.TES5Type.NativeType)) { subfragmentProperty.TES5Type.NativeType = existingProperty.TES5Type.NativeType; existingProperty.TES5Type = subfragmentProperty.TES5Type; continue; } throw new ConversionException("Types were not compatible for property " + subfragmentProperty.Name + ": " + subfragmentProperty.TES5Type.Value + " should extend " + existingProperty.TES5Type.Value + " (" + existingProperty.TES5Type.NativeType.Value + ")."); } } List <ITES5CodeBlock> subfragmentBlocks = subfragmentScript.BlockList.Blocks; if (subfragmentBlocks.Count != 1) { throw new ConversionException("Wrong QF fragment, actual function count: " + subfragmentBlocks.Count + ".."); } ITES5CodeBlock subfragmentBlock = subfragmentBlocks[0]; if (subfragmentBlock.FunctionScope.BlockName != TES5FragmentFactory.GetFragmentName(0)) { throw new ConversionException("Wrong QF fragment funcname, actual function name: " + subfragmentBlock.FunctionScope.BlockName + "."); } string newFragmentFunctionName = TES5FragmentFactory.GetFragmentName(subfragment.Stage, subfragment.LogIndex); subfragmentBlock.FunctionScope.Rename(newFragmentFunctionName); List <int>?stageMapOfStage = stageMap.TryGetStageTargetsMap(subfragment.Stage); if (stageMapOfStage != null) { var objectiveCodeChunks = objectiveHandlingFactory.GenerateObjectiveHandling(subfragmentBlock, resultingGlobalScope, stageMapOfStage); foreach (var newCodeChunk in objectiveCodeChunks) { subfragmentBlock.AddChunk(newCodeChunk); } } questStageBlocks.Add(new QuestStageBlock(subfragment.Stage, subfragment.LogIndex, subfragmentBlock)); implementedStages.Add(subfragment.Stage); } /* * Diff to find stages which we still need to mark */ int[] nonDoneStages = stageMap.StageIDs.Where(stageID => !implementedStages.Contains(stageID)).ToArray(); foreach (int nonDoneStage in nonDoneStages) { TES5FunctionCodeBlock fragment = objectiveHandlingFactory.CreateEnclosedFragment(resultingGlobalScope, nonDoneStage, stageMap.GetStageTargetsMap(nonDoneStage)); questStageBlocks.Add(new QuestStageBlock(nonDoneStage, 0, fragment)); } this.mappedTargetsLogService.WriteScriptName(resultingFragmentName); foreach (var kvp in stageMap.MappedTargetsIndex) { var originalTargetIndex = kvp.Key; var mappedTargetIndexes = kvp.Value; this.mappedTargetsLogService.WriteLine(originalTargetIndex, mappedTargetIndexes); } TES5BlockList resultingBlockList = new TES5BlockList(questStageBlocks.OrderBy(b => b.StageID).ThenBy(b => b.LogIndex).Select(b => b.CodeBlock)); TES5Script resultingTree = new TES5Script(resultingGlobalScope, resultingBlockList, true); string outputPath = target.GetTranspileToPath(resultingFragmentName); return(new TES5Target(resultingTree, outputPath)); }