public static void CheckAfter(BuildTool_BlueprintPaste __instance, ref bool __result, ref bool __state) { if (__result) { return; } if (!BlueprintCopyExtension.isEnabled || !__state) { return; } if (!__instance.cannotBuild || reformPreviews.Count <= 0) { return; } if (NebulaModAPI.IsMultiplayerActive && NebulaModAPI.MultiplayerSession.Factories.IsIncomingRequest.Value) { return; } BPGratBox box = ReformBPUtils.GetBoundingRange(__instance.planet, __instance.actionBuild.planetAux, new int[0], 0, reformPreviews, reformPreviews[0].longitude); bool allOk = true; for (int i = 0; i < __instance.bpCursor; i++) { BuildPreview preview = __instance.bpPool[i]; if (preview.condition == EBuildCondition.NeedGround) { Vector3 pos = (preview.lpos + preview.lpos2) * 0.5f; if (box.InGratBox(pos)) { preview.condition = EBuildCondition.Ok; } } if (preview.condition != EBuildCondition.Ok && preview.condition != EBuildCondition.NotEnoughItem) { allOk = false; } } if (allOk) { __result = true; } }
public static void SelectionSub(BuildTool_BlueprintCopy __instance) { if (GameMain.localPlanet == null || GameMain.localPlanet.type == EPlanetType.Gas) { return; } reformPreSelection.Clear(); if (Mathf.Abs(__instance.preSelectArcBox.x - __instance.preSelectArcBox.z) < 0.01f && Mathf.Abs(__instance.preSelectArcBox.y - __instance.preSelectArcBox.w) < 0.01f && __instance.castObjectId != 0) { return; } ReformBPUtils.currentGrid = GameMain.localPlanet.aux.mainGrid; ReformBPUtils.ClearDisplay(); ReformBPUtils.DisplayPos(__instance.preSelectGratBox.startLatitudeRad, __instance.preSelectGratBox.startLongitudeRad, Color.green); ReformBPUtils.DisplayPos(__instance.preSelectGratBox.endLatitudeRad, __instance.preSelectGratBox.endLongitudeRad, Color.yellow); bool full = Mathf.Abs(__instance.preSelectArcBox.startLongitudeRad - __instance.preSelectArcBox.endLongitudeRad) > 2 * Mathf.PI - 0.04f; BPGratBox[] areas = ReformBPUtils.SplitGratBox(__instance.preSelectGratBox); foreach (BPGratBox box in areas) { ReformBPUtils.ItterateOnReform(__instance, box, (index, data) => { if (reformSelection.ContainsKey(index)) { reformSelection.Remove(index); } }, full); } }
public static bool CreateBox(BuildTool_BlueprintCopy __instance) { __instance.curActiveAreaGratBoxCursor = 0; CopyToTempArray(__instance); CopyReforms(); BPGratBox gratbox = ReformBPUtils.GetBoundingRange(__instance.planet, __instance.actionBuild.planetAux, __instance._tmp_selected_ids, __instance._tmp_selected_cnt, tmpReformList, __instance.divideLineRad); if (__instance.selectedObjIds.Count > 0 || reformSelection.Count > 0) { float longitudeRadPerGrid = BlueprintUtils.GetLongitudeRadPerGrid(gratbox.startLatitudeRad, __instance.segment); float latitudeRadPerGrid = BlueprintUtils.GetLatitudeRadPerGrid(__instance.segment); float extend_lng_grid = Math.Max(3f - Mathf.RoundToInt(gratbox.width / longitudeRadPerGrid) / 2, 1f); float extend_lat_grid = Math.Max(3f - Mathf.RoundToInt(gratbox.height / latitudeRadPerGrid) / 2, 1f); gratbox = BlueprintUtils.GetExtendedGratBox(gratbox, extend_lng_grid, extend_lat_grid); __instance.curActiveAreaGratBoxCursor = BlueprintUtils.SplitGratBoxInTropicAreas(gratbox, __instance.tropicGratBoxRadRangeArr, __instance.displayGratBoxArr, __instance.segment); Array.Clear(__instance._tmp_selected_ids, 0, __instance._tmp_selected_ids.Length); } return(false); }
public static void OnUpdate(BuildTool_BlueprintPaste __instance) { if (!BlueprintCopyExtension.isEnabled) { return; } if (reformPreviews.Count <= 0) { return; } if (__instance.cannotBuild) { return; } tickCounter++; if (tickCounter >= 30) { tickCounter = 0; Vector3 center = Vector3.zero; tmpPoints.Clear(); PlatformSystem platformSystem = __instance.factory.platformSystem; foreach (ReformData preview in reformPreviews) { ReformBPUtils.GetSegmentCount(preview.latitude, preview.longitude, out float latCount, out float longCount, out int segmentCount); longCount = Mathf.Repeat(longCount, segmentCount); int reformIndex = platformSystem.GetReformIndexForSegment(latCount, longCount); if (reformIndex < 0) { continue; } int type = platformSystem.GetReformType(reformIndex); if (platformSystem.IsTerrainReformed(type)) { continue; } Vector3 pos = BlueprintUtils.GetDir(preview.longitude, preview.latitude); pos *= GameMain.localPlanet.realRadius + 0.2f; tmpPoints.Add(pos); center += pos; } lastCost = ReformBPUtils.ComputeFlattenTerrainReform(__instance.factory, tmpPoints, center); } string message = ""; int playerFoundationCount = __instance.player.package.GetItemCount(PlatformSystem.REFORM_ID); if (playerFoundationCount < tmpPoints.Count) { message = Format("NotEnoughFoundationsMessage".Translate(), tmpPoints.Count - playerFoundationCount) + "\n"; } else { message = Format("FoundCountMessage".Translate(), tmpPoints.Count) + "\n"; } if (__instance.cursorValid && !VFInput.onGUIOperate) { if (lastCost > 0) { __instance.actionBuild.model.cursorText = $"{message}{"沙土消耗".Translate()} {lastCost} {"个沙土".Translate()}"; } else if (lastCost == 0) { __instance.actionBuild.model.cursorText = $"{message}"; } else { int num2 = -lastCost; __instance.actionBuild.model.cursorText = $"{message}{"沙土获得".Translate()} {num2} {"个沙土".Translate()}"; } } }
public static bool CalculatePositions(BuildTool_BlueprintPaste tool, List <ReformData> reforms, Color[] colors) { ReformBPUtils.currentGrid = tool.factory.planet.aux.mainGrid; PlanetData planet = tool.factory.planet; PlatformSystem platformSystem = tool.factory.platformSystem; Vector3 center = Vector3.zero; tmpPoints.Clear(); foreach (ReformData preview in reforms) { ReformBPUtils.GetSegmentCount(preview.latitude, preview.longitude, out float latCount, out float longCount, out int segmentCount); longCount = Mathf.Repeat(longCount, segmentCount); int reformIndex = platformSystem.GetReformIndexForSegment(latCount, longCount); if (reformIndex < 0) { continue; } int type = platformSystem.GetReformType(reformIndex); if (platformSystem.IsTerrainReformed(type)) { continue; } Vector3 pos = BlueprintUtils.GetDir(preview.longitude, preview.latitude); pos *= planet.realRadius + 0.2f; tmpPoints.Add(pos); center += pos; } int cost = ReformBPUtils.ComputeFlattenTerrainReform(tool.factory, tmpPoints, center); if (NebulaModAPI.IsMultiplayerActive) { IMultiplayerSession session = NebulaModAPI.MultiplayerSession; if (!session.Factories.IsIncomingRequest.Value && !CheckItems(tool, cost, tmpPoints.Count)) { return(false); } if (session.LocalPlayer.IsHost) { int planetId = session.Factories.EventFactory?.planetId ?? GameMain.localPlanet?.id ?? -1; session.Network.SendPacketToStar(new ReformPasteEventPacket(planetId, reforms, colors, session.Factories.PacketAuthor == NebulaModAPI.AUTHOR_NONE ? session.LocalPlayer.Id : session.Factories.PacketAuthor), GameMain.galaxy.PlanetById(planetId).star.id); } //If client builds, he need to first send request to the host and wait for reply if (!session.LocalPlayer.IsHost && !session.Factories.IsIncomingRequest.Value) { session.Network.SendPacket(new ReformPasteEventPacket(GameMain.localPlanet?.id ?? -1, reforms, colors, session.Factories.PacketAuthor == NebulaModAPI.AUTHOR_NONE ? session.LocalPlayer.Id : session.Factories.PacketAuthor)); return(true); } } else { if (!CheckItems(tool, cost, tmpPoints.Count)) { return(false); } } if (colors != null && colors.Length > 0) { ApplyColors(tool, colors); } ReformBPUtils.FlattenTerrainReform(tool.factory, tmpPoints, center); VFAudio.Create("reform-terrain", null, center, true, 4); foreach (ReformData preview in reforms) { ReformBPUtils.GetSegmentCount(preview.latitude, preview.longitude, out float latCount, out float longCount, out int segmentCount); longCount = Mathf.Repeat(longCount, segmentCount); int reformIndex = platformSystem.GetReformIndexForSegment(latCount, longCount); if (reformIndex < 0) { continue; } int reformType = platformSystem.GetReformType(reformIndex); int reformColor = platformSystem.GetReformColor(reformIndex); if (reformType == preview.type && reformColor == preview.color) { continue; } platformSystem.SetReformType(reformIndex, preview.type); platformSystem.SetReformColor(reformIndex, preview.color); } return(true); }
static IEnumerable <CodeInstruction> AddMoreData(IEnumerable <CodeInstruction> instructions, ILGenerator generator) { CodeMatcher matcher = new CodeMatcher(instructions, generator) .MatchForward(true, new CodeMatch(OpCodes.Ldarg_S), new CodeMatch(OpCodes.Ldc_I4_0) ).Advance(3); Label contLabel = (Label)matcher.Operand; //allow generation when there is no buildings matcher.Advance(-3) .SetAndAdvance(OpCodes.Pop, null) .InsertAndAdvance(Transpilers.EmitDelegate <Func <bool> >(() => BlueprintCopyExtension.isEnabled && BlueprintCopyExtension.reformSelection.Count > 0)) .InsertAndAdvance(new CodeInstruction(OpCodes.Brtrue, contLabel)) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_S, 4)) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldc_I4_0)); //Replace function call to include foundations matcher.MatchForward(false, new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(BlueprintUtils), nameof(BlueprintUtils.GetBoundingRange)))) .SetInstruction(Transpilers.EmitDelegate <Func <PlanetData, PlanetAuxData, int[], int, float, BPGratBox> >((data, auxData, arg3, i, f) => { BlueprintCopyExtension.CopyReforms(); return(ReformBPUtils.GetBoundingRange(data, auxData, arg3, i, BlueprintCopyExtension.tmpReformList, f)); })); //Add initialization matcher.MatchForward(false, new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(OpCodes.Ldloc_S), new CodeMatch(OpCodes.Newarr), new CodeMatch(OpCodes.Stfld) ).Advance(1) .InsertAndAdvance(Transpilers.EmitDelegate <Action <BlueprintData> >(data => { if (BlueprintCopyExtension.isEnabled && !UndoManager.IgnoreAllEvents.Value) { data.reforms = new ReformData[BlueprintCopyExtension.reformSelection.Count]; int i = 0; foreach (var kv in BlueprintCopyExtension.reformSelection) { data.reforms[i] = kv.Value; data.reforms[i].areaIndex = -1; i++; } } else { data.reforms = new ReformData[0]; } })) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0)); //Just to anchor matcher.MatchForward(true, new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(BlueprintUtils), nameof(BlueprintUtils.GetLongitudeSegmentCount), new[] { typeof(Vector3), typeof(int) })), new CodeMatch(OpCodes.Stloc_S), new CodeMatch(OpCodes.Ldloc_S), new CodeMatch(OpCodes.Ldloc_S), new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(BlueprintUtils), nameof(BlueprintUtils.GetLongitudeRadPerGrid), new[] { typeof(int), typeof(int) }))); // add my code matcher.MatchForward(false, new CodeMatch(OpCodes.Ldc_I4_0), new CodeMatch(OpCodes.Stloc_S)) .Advance(1) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0)) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 18)) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 17)) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 7)) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 20)) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 11)) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 19)) .InsertAndAdvance(Transpilers.EmitDelegate <AddAction>( (blueprint, bpgratBox, i, array, longitudeRadPerGrid, latitudeRadPerGrid, longitudeSegmentCount) => { if (!BlueprintCopyExtension.isEnabled) { return; } if (UndoManager.IgnoreAllEvents.Value) { return; } for (int j = 0; j < BlueprintCopyExtension.reformSelection.Count; j++) { if (blueprint.reforms[j].areaIndex >= 0) { continue; } ReformData data = blueprint.reforms[j]; if (!(bpgratBox.y - 1E-05f <= data.latitude) || !(data.latitude <= bpgratBox.w + 1E-05f)) { continue; } blueprint.reforms[j].areaIndex = i; blueprint.reforms[j].localLongitude = (data.longitude - array[i].x) / longitudeRadPerGrid; blueprint.reforms[j].localLatitude = (data.latitude - array[i].y) / latitudeRadPerGrid; if (blueprint.reforms[j].localLongitude < -0.5001f) { blueprint.reforms[j].localLongitude += longitudeSegmentCount * 5; } } })); //Add null check to buildings iteration matcher.MatchForward(true, new CodeMatch(OpCodes.Ldc_I4_0), new CodeMatch(OpCodes.Newarr), new CodeMatch(OpCodes.Stfld)) .Advance(8) .CreateLabel(out Label exitLabel) .Advance(-2) .InsertAndAdvance(new CodeInstruction(OpCodes.Pop)) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_2)) .InsertAndAdvance(new CodeInstruction(OpCodes.Brfalse, exitLabel)) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 21)); return(matcher.InstructionEnumeration()); }
public static void Update(UIBuildingGrid __instance) { if (!BlueprintCopyExtension.isEnabled) { return; } Player mainPlayer = GameMain.mainPlayer; PlanetFactory planetFactory = GameMain.localPlanet?.factory; if (planetFactory == null) { return; } if (GameMain.localPlanet.type == EPlanetType.Gas) { return; } PlayerAction_Build actionBuild = mainPlayer?.controller.actionBuild; if (actionBuild == null) { return; } if (__instance.reformCursorMap == null) { return; } int maxLen = __instance.reformCursorMap.Length; PlatformSystem system = planetFactory.platformSystem; if (system == null) { return; } system.EnsureReformData(); if (actionBuild.blueprintMode == EBlueprintMode.None) { __instance.material.SetColor(cursorColor, Color.white); return; } float realRadius = GameMain.localPlanet.realRadius; __instance.displayScale = (realRadius + 0.2f) * 2f; if (currentFactory == null || currentFactory.index != planetFactory.index) { currentFactory = planetFactory; fakeReformData = new byte[system.maxReformCount]; Array.Copy(system.reformData, fakeReformData, system.maxReformCount); } if (actionBuild.blueprintMode == EBlueprintMode.Copy) { bool any = false; if (BlueprintCopyExtension.reformSelection.Count > 0) { __instance.material.SetColor(cursorColor, displayColor); foreach (var kv in BlueprintCopyExtension.reformSelection) { int index = kv.Key; if (index >= 0 && index < maxLen) { if (BlueprintCopyExtension.reformPreSelection.Count == 0) { fakeReformData[index] = 0; } __instance.reformCursorMap[index] = 1; } } any = true; } if (BlueprintCopyExtension.reformPreSelection.Count > 0) { __instance.material.SetColor(cursorColor, selectColor); foreach (var kv in BlueprintCopyExtension.reformPreSelection) { int index = kv.Key; if (index >= 0 && index < maxLen) { fakeReformData[index] = 0; __instance.reformCursorMap[index] = 1; } } any = true; } if (any) { __instance.material.SetColor(tintColor, Color.clear); __instance.gridRnd.enabled = true; __instance.material.SetFloat(reformMode, 1f); __instance.material.SetFloat(zMin, -1.5f); __instance.reformCursorBuffer.SetData(__instance.reformCursorMap); __instance.material.SetBuffer(cursorBuffer, __instance.reformCursorBuffer); ComputeBuffer reformDataBuffer = system.reformDataBuffer; reformDataBuffer.SetData(fakeReformData); __instance.material.SetBuffer(dataBuffer, reformDataBuffer); foreach (var kv in BlueprintCopyExtension.reformSelection) { int index = kv.Key; if (index >= 0 && index < maxLen) { if (BlueprintCopyExtension.reformPreSelection.Count == 0) { fakeReformData[index] = system.reformData[index]; } __instance.reformCursorMap[index] = 0; } } foreach (var kv in BlueprintCopyExtension.reformPreSelection) { int index = kv.Key; if (index >= 0 && index < maxLen) { fakeReformData[index] = system.reformData[index]; __instance.reformCursorMap[index] = 0; } } } } if (actionBuild.blueprintMode == EBlueprintMode.Paste) { ReformBPUtils.currentGrid = GameMain.localPlanet.aux.mainGrid; __instance.material.SetColor(cursorColor, displayColor); __instance.gridRnd.enabled = true; PlatformSystem platformSystem = __instance.reformMapPlanet.factory.platformSystem; if (BlueprintPasteExtension.reformPreviews.Count > 0) { foreach (ReformData reformPreview in BlueprintPasteExtension.reformPreviews) { ReformBPUtils.GetSegmentCount(reformPreview.latitude, reformPreview.longitude, out float latCount, out float longCount, out int segmentCount); longCount = Mathf.Repeat(longCount, segmentCount); int index = platformSystem.GetReformIndexForSegment(latCount, longCount); if (index >= 0 && index < maxLen) { __instance.reformCursorMap[index] = 1; } } __instance.material.SetColor(tintColor, Color.clear); __instance.material.SetFloat(reformMode, 1f); __instance.material.SetFloat(zMin, -1.5f); __instance.reformCursorBuffer.SetData(__instance.reformCursorMap); __instance.material.SetBuffer(cursorBuffer, __instance.reformCursorBuffer); foreach (ReformData reformPreview in BlueprintPasteExtension.reformPreviews) { ReformBPUtils.GetSegmentCount(reformPreview.latitude, reformPreview.longitude, out float latCount, out float longCount, out int segmentCount); longCount = Mathf.Repeat(longCount, segmentCount); int index = platformSystem.GetReformIndexForSegment(latCount, longCount); if (index >= 0 && index < maxLen) { __instance.reformCursorMap[index] = 0; } } } } }