Exemplo n.º 1
0
        private void SetIsTargetObjective(ICombatant combatant)
        {
            Main.LogDebug($"[SetUnitsInRegionToBeTaggedObjectiveTargetsResult] Setting isObjectiveTarget '{IsObjectiveTarget}' for '{combatant.GameRep.name} - {combatant.DisplayName}'");
            ObstructionGameLogic obstructionGameLogic = combatant.GameRep.GetComponent <ObstructionGameLogic>();

            obstructionGameLogic.isObjectiveTarget = true;

            if (Type == "Building")
            {
                BattleTech.Building building = combatant as BattleTech.Building;
                AccessTools.Field(typeof(BattleTech.Building), "isObjectiveTarget").SetValue(building, true);
                building.BuildingRep.IsTargetable = true;
            }

            CombatHUDInWorldElementMgr inworldElementManager = GameObject.Find("uixPrfPanl_HUD(Clone)").GetComponent <CombatHUDInWorldElementMgr>();

            AccessTools.Method(typeof(CombatHUDInWorldElementMgr), "AddTickMark").Invoke(inworldElementManager, new object[] { combatant });
            AccessTools.Method(typeof(CombatHUDInWorldElementMgr), "AddInWorldActorElements").Invoke(inworldElementManager, new object[] { combatant });

            if (Type == "Building")
            {
                CombatHUDNumFlagHex        numFlagEx = inworldElementManager.GetNumFlagForCombatant(combatant);
                CombatHUDFloatieStackActor floatie   = inworldElementManager.GetFloatieStackForCombatant(combatant);

                numFlagEx.anchorPosition = CombatHUDInWorldScalingActorInfo.AnchorPosition.Feet;
                floatie.anchorPosition   = CombatHUDInWorldScalingActorInfo.AnchorPosition.Feet;
            }
        }
        public static void Postfix(Building __instance)
        {
            List <MapEncounterLayerDataCell> cells = ObstructionGameLogic.GetObstructionFromBuilding(
                __instance
                , UnityGameInstance.BattleTechGame.Combat.ItemRegistry)
                                                     .occupiedCells;

            foreach (var cell in cells)
            {
                if (cell.relatedTerrainCell is MapTerrainDataCellEx ex)
                {
                    ex.UpdateWaterHeight();
                }
            }
        }
        public void ResetAllBuildingData()
        {
            Main.LogDebug($"[EncounterDataManager.ResetAllBuildingData] Resetting all old building data");
            List <BuildingRepresentation> buildingsInMap = GameObjextExtensions.GetBuildingsInMap();

            foreach (BuildingRepresentation buildingRep in buildingsInMap)
            {
                BattleTech.Building building = buildingRep.ParentBuilding;

                if (building != null)
                {
                    AccessTools.Field(typeof(BattleTech.Building), "isObjectiveTarget").SetValue(building, false);
                    AccessTools.Field(typeof(BattleTech.Building), "isObjectiveActive").SetValue(building, false);
                    building.objectiveGUIDS.Clear();
                }

                ObstructionGameLogic obstructionGameLogic = buildingRep.GetComponent <ObstructionGameLogic>();
                if (obstructionGameLogic != null)
                {
                    obstructionGameLogic.isObjectiveTarget = false;
                }
            }
        }
Exemplo n.º 4
0
        public override void Trigger(MessageCenterMessage inMessage, string triggeringName)
        {
            Main.LogDebug($"[SetIsObjectiveTargetByTagResult] Setting IsObjectiveTarget '{IsObjectiveTarget}' with tags '{String.Concat(Tags)}'");
            List <ICombatant> combatants = ObjectiveGameLogic.GetTaggedCombatants(UnityGameInstance.BattleTechGame.Combat, new TagSet(Tags));

            Main.LogDebug($"[SetIsObjectiveTargetByTagResult] Found '{combatants.Count}' combatants");

            foreach (ICombatant combatant in combatants)
            {
                BattleTech.Building building = combatant as BattleTech.Building;

                if (building != null)
                {
                    Main.LogDebug($"[SetIsObjectiveTargetByTagResult] Found building '{building.GameRep.name} - {building.DisplayName}'");
                    ObstructionGameLogic obstructionGameLogic = building.GameRep.GetComponent <ObstructionGameLogic>();
                    obstructionGameLogic.isObjectiveTarget = true;
                    AccessTools.Field(typeof(BattleTech.Building), "isObjectiveTarget").SetValue(combatant, true);
                }

                CombatHUDInWorldElementMgr inworldElementManager = GameObject.Find("uixPrfPanl_HUD(Clone)").GetComponent <CombatHUDInWorldElementMgr>();
                AccessTools.Method(typeof(CombatHUDInWorldElementMgr), "AddTickMark").Invoke(inworldElementManager, new object[] { combatant });
                AccessTools.Method(typeof(CombatHUDInWorldElementMgr), "AddInWorldActorElements").Invoke(inworldElementManager, new object[] { combatant });
            }
        }
        static void Postfix(LineOfSight __instance, Point p0, float height0, Point p1, float height1, Vector3 unitDelta, string targetGuid,
                            ref float __result, CombatGameState ___Combat)
        {
            if (ModState.CurrentTurretForLOS == null)
            {
                return;
            }

            if (p0.X == p1.X && p0.Z == p1.Z)
            {
                __result = 0f;
                return;
            }

            if (!___Combat.MapMetaData.IsWithinBounds(p0) || !___Combat.MapMetaData.IsWithinBounds(p1))
            {
                __result = float.MaxValue;
                return;
            }

            float numCellsX       = Mathf.Abs(unitDelta.x) * (float)MapMetaDataExporter.cellSize;
            float numCellsY       = Mathf.Abs(unitDelta.z) * (float)MapMetaDataExporter.cellSize;
            float lineDeltaX      = (float)(p1.X - p0.X);
            float lineDeltaZ      = (float)(p1.Z - p0.Z);
            float greatestDivisor = Mathf.Max(Mathf.Abs(lineDeltaX), Mathf.Abs(lineDeltaZ));
            float stepHeight      = (height1 - height0) / greatestDivisor;
            float sumVisionCost   = 0f;

            Traverse           projectedHeightAtT = Traverse.Create(__instance).Method("getProjectedHeightAt", new Type[] { typeof(Point), typeof(float), typeof(Point), typeof(float) });
            Traverse           visCostOfCellT     = Traverse.Create(__instance).Method("visCostOfCell", new Type[] { typeof(MapTerrainDataCell), typeof(float) });
            string             shellBuildingGUID  = ModState.AmbushTurretGUIDtoBuilding[ModState.CurrentTurretForLOS.GUID].GUID;
            EncounterLayerData encounterLayerData = ___Combat.EncounterLayerData;

            List <Point> list = BresenhamLineUtil.BresenhamLine(p0, p1);

            for (int i = 1; i < list.Count; i++)
            {
                float stepDelta;
                if (list[i].X != list[i - 1].X)
                {
                    stepDelta = numCellsX;
                }
                else
                {
                    stepDelta = numCellsY;
                }

                // Increment vision cost only slightly if it's inside our shell building
                if (encounterLayerData.mapEncounterLayerDataCells[list[i].Z, list[i].X].HasSpecifiedBuilding(shellBuildingGUID))
                {
                    Mod.Log.Trace?.Write($" Point x={list[i].X} z={list[i].Z} is inside the shell building, adding vision cost normally.");
                    sumVisionCost += stepDelta;
                }
                else
                {
                    float projectedHeightAt = projectedHeightAtT.GetValue <float>(new object[] { p0, height0, list[i], stepHeight });
                    MapTerrainDataCell mapTerrainDataCell = ___Combat.MapMetaData.mapTerrainDataCells[list[i].Z, list[i].X];
                    if (mapTerrainDataCell.cachedHeight > projectedHeightAt)
                    {
                        if (mapTerrainDataCell.MapEncounterLayerDataCell.HasBuilding)
                        {
                            for (int j = 0; j < mapTerrainDataCell.MapEncounterLayerDataCell.buildingList.Count; j++)
                            {
                                if (ObstructionGameLogic.GuidsMatchObjectOrRep(mapTerrainDataCell.MapEncounterLayerDataCell.buildingList[j].buildingGuid, targetGuid))
                                {
                                    __result = sumVisionCost;
                                    return;
                                }
                            }
                        }

                        __result = float.MaxValue;
                        return;
                    }

                    sumVisionCost += visCostOfCellT.GetValue <float>(new object[] { mapTerrainDataCell, projectedHeightAt }) * stepDelta;
                }
            }

            __result = sumVisionCost;
            return;
        }
        public void GenerateEncounterLayerBuildingData()
        {
            Main.Logger.LogDebug($"[EncounterDataManager.GenerateEncounterLayerBuildingData] Generating building data");
            Terrain terrain            = Terrain.activeTerrain;
            float   terrainZSize       = terrain.terrainData.size.z;
            float   terrainXSize       = terrain.terrainData.size.x;
            Vector3 terrainPosition    = terrain.transform.position;
            float   halfMapCellSize    = (float)MapMetaDataExporter.cellSize / 2f;
            int     halfMapCellSizeInt = MapMetaDataExporter.cellSize / 2;
            EncounterLayerParent encounterLayerParent = MissionControl.Instance.EncounterLayerParent;
            EncounterLayerData   encounterLayerData   = MissionControl.Instance.EncounterLayerData;
            MapMetaDataExporter  mapMetaExporter      = encounterLayerParent.GetComponent <MapMetaDataExporter>();
            MapMetaData          mapMetaData          = UnityGameInstance.BattleTechGame.Combat.MapMetaData;
            Vector3 raycastOrigin = new Vector3(0f, 1000f, 0f);

            // Lookups
            Dictionary <string, int>    regionRaycastHits         = new Dictionary <string, int>();
            List <RegionGameLogic>      regionGameObjectList      = new List <RegionGameLogic>();
            List <ObstructionGameLogic> obstructionGameObjectList = new List <ObstructionGameLogic>();

            // Marks only the ObstructionGameLogic objects for ray tracing for performance reasons
            AccessTools.Method(typeof(MapMetaDataExporter), "MarkCellsForRaycasting").Invoke(mapMetaExporter, new object[] { mapMetaData.mapTerrainDataCells, (int)terrain.transform.position.x, (int)terrain.transform.position.z });

            // TODO: Maybe wipe region building lists. Not sure if I really need/want this yet
            RegionGameLogic[] componentsInChildren = encounterLayerData.GetComponentsInChildren <RegionGameLogic>();
            for (int i = 0; i < componentsInChildren.Length; i++)
            {
                componentsInChildren[i].InitRegionForRayCasting();
            }

            // Iterate over the Z cell range
            for (float i = halfMapCellSize; i < terrainZSize; i += (float)MapMetaDataExporter.cellSize)
            {
                int zCellIndex = (int)i / MapMetaDataExporter.cellSize;

                // Iterate over the X cell range
                for (float j = halfMapCellSize; j < terrainXSize; j += (float)MapMetaDataExporter.cellSize)
                {
                    int xCellIndex = (int)j / MapMetaDataExporter.cellSize;

                    MapEncounterLayerDataCell mapEncounterLayerDataCell = new MapEncounterLayerDataCell();
                    if (mapMetaData.mapTerrainDataCells[zCellIndex, xCellIndex].doRayCast)
                    {
                        int hitIndex = 0;
                        regionRaycastHits.Clear();
                        regionGameObjectList.Clear();
                        obstructionGameObjectList.Clear();

                        for (int k = -halfMapCellSizeInt; k < halfMapCellSizeInt; k++)
                        {
                            raycastOrigin.z = i + (float)k + terrainPosition.z;

                            for (int l = -halfMapCellSizeInt; l < halfMapCellSizeInt; l++)
                            {
                                raycastOrigin.x = j + (float)l + terrainPosition.x;

                                RaycastHit[] raycastHits          = Physics.RaycastAll(raycastOrigin, Vector3.down);
                                List <ObstructionGameLogic> list3 = new List <ObstructionGameLogic>();

                                // Go through all the raycasts at Z,X of the terrain by cell size (middle of cell)
                                // Then find any regions hit, record the number of hits/cells the region has
                                for (int m = 0; m < raycastHits.Length; m++)
                                {
                                    RegionGameLogic regionGameLogic = raycastHits[m].transform.GetComponent <RegionGameLogic>();
                                    if (regionGameLogic != null)
                                    {
                                        if (!regionRaycastHits.ContainsKey(regionGameLogic.encounterObjectGuid))
                                        {
                                            regionRaycastHits[regionGameLogic.encounterObjectGuid] = 1;
                                        }
                                        else
                                        {
                                            string encounterObjectGuid = regionGameLogic.encounterObjectGuid;
                                            regionRaycastHits[encounterObjectGuid]++;
                                        }

                                        // Cache the region in the lookup
                                        if (!regionGameObjectList.Contains(regionGameLogic))
                                        {
                                            regionGameObjectList.Add(regionGameLogic);
                                        }
                                    }

                                    ObstructionGameLogic obstructionGameLogicInParent = raycastHits[m].transform.GetComponentInParent <ObstructionGameLogic>();
                                    if (obstructionGameLogicInParent != null && raycastHits[m].point.y > mapMetaData.mapTerrainDataCells[zCellIndex, xCellIndex].terrainHeight)
                                    {
                                        if (obstructionGameLogicInParent.IsBuildingHitAddWorthy)
                                        {
                                            if (!obstructionGameObjectList.Contains(obstructionGameLogicInParent))
                                            {
                                                obstructionGameObjectList.Add(obstructionGameLogicInParent);
                                            }
                                        }

                                        Vector3            normal             = raycastHits[m].normal;
                                        BuildingRaycastHit buildingRaycastHit = new BuildingRaycastHit {
                                            buildingSteepness = 90f - 57.29578f * Mathf.Atan2(normal.y, Mathf.Sqrt(normal.x * normal.x + normal.z * normal.z)),
                                            buildingHeight    = raycastHits[m].point.y,
                                            buildingGuid      = obstructionGameLogicInParent.encounterObjectGuid,
                                            hitIndex          = hitIndex
                                        };
                                        mapEncounterLayerDataCell.AddBuildingHit(buildingRaycastHit);
                                    }
                                }
                                hitIndex++;
                            }
                        }

                        // For all the regions detected, if it exists in 10 or more cells - add the region to the map encounter layer data (this is vanilla... why?!)
                        // And all all obstruction games logics to the region
                        foreach (RegionGameLogic regionGameLogic in regionGameObjectList)
                        {
                            if (regionRaycastHits[regionGameLogic.encounterObjectGuid] >= 10)
                            {
                                mapEncounterLayerDataCell.AddRegion(regionGameLogic);
                                foreach (ObstructionGameLogic obstructionGameLogic in obstructionGameObjectList)
                                {
                                    regionGameLogic.AddBuildingGuidToRegion(obstructionGameLogic.encounterObjectGuid);
                                }
                            }
                        }
                        mapEncounterLayerDataCell.AverageTheBuildingHits();
                        mapEncounterLayerDataCell.SortBuildingListByHeight();
                    }

                    encounterLayerData.mapEncounterLayerDataCells[zCellIndex, xCellIndex] = mapEncounterLayerDataCell;
                    encounterLayerData.mapEncounterLayerDataCells[zCellIndex, xCellIndex].relatedTerrainCell = mapMetaData.mapTerrainDataCells[zCellIndex, xCellIndex];
                    mapMetaData.mapTerrainDataCells[zCellIndex, xCellIndex].MapEncounterLayerDataCell        = mapEncounterLayerDataCell;
                }
            }
        }