/// <see cref="IMapEditor.RemoveTerrainObject"/> public void RemoveTerrainObject(IMapAccess targetMap, ITerrainObject terrainObject) { if (targetMap == null) { throw new ArgumentNullException("targetMap"); } if (terrainObject == null) { throw new ArgumentNullException("terrainObject"); } if (targetMap != terrainObject.ParentMap) { throw new InvalidOperationException("The map of the terrain object must equal with the target map!"); } /// TODO: Avoid this downcast! MapAccess targetMapObj = targetMap as MapAccess; if (targetMapObj == null) { throw new ArgumentException("The given map cannot be handled by the MapEditor!", "targetMap"); } /// Undo the cell data changesets of the removed terrain object. foreach (ICellDataChangeSet changeset in terrainObject.Type.CellDataChangesets) { changeset.Undo(terrainObject); } targetMapObj.DetachTerrainObject(terrainObject); }
/// <summary> /// Checks whether the given area with the given center tile is a subset of the given layer. /// </summary> /// <param name="map">Reference to the map.</param> /// <param name="center">The center of the area to check.</param> /// <param name="layer">The terrain type of the layer to check.</param> /// <param name="area">The area to check.</param> /// <returns>True if the area is a subset of the given layer, false otherwise.</returns> private bool CheckLayer(IMapAccess map, IIsoTile center, ITerrainType layer, FloodArea area) { foreach (FloodItem floodItem in area) { IIsoTile checkedTile = map.GetIsoTile(center.MapCoords + floodItem.Coordinates); if (checkedTile != null) { if (checkedTile.Type.TerrainA.IsDescendantOf(layer) || checkedTile.Type.TerrainA == layer) { continue; } if (checkedTile.Type.Combination != TerrainCombination.Simple) { if (checkedTile.Type.TerrainB == layer) { /// We have to check the combinations if (((int)floodItem.Combination & (int)checkedTile.Type.Combination) != (int)floodItem.Combination) { return(false); } } else { return(false); } } else { return(false); } } } return(true); }
/// <see cref="ITerrainObjectType.CheckTerrainObjectIntersections"/> public RCSet <RCIntVector> CheckTerrainObjectIntersections(IMapAccess map, RCIntVector position) { if (map == null) { throw new ArgumentNullException("map"); } if (position == RCIntVector.Undefined) { throw new ArgumentNullException("position"); } RCSet <RCIntVector> retList = new RCSet <RCIntVector>(); for (int quadX = 0; quadX < this.quadraticSize.X; quadX++) { for (int quadY = 0; quadY < this.quadraticSize.Y; quadY++) { RCIntVector relQuadCoords = new RCIntVector(quadX, quadY); RCIntVector absQuadCoords = position + relQuadCoords; if (absQuadCoords.X >= 0 && absQuadCoords.X < map.Size.X && absQuadCoords.Y >= 0 && absQuadCoords.Y < map.Size.Y) { /// Check intersection with other terrain object at the current quadratic tile. ITerrainObject objToCheck = map.GetQuadTile(absQuadCoords).TerrainObject; if (objToCheck != null && !this.IsExcluded(relQuadCoords) && objToCheck.GetQuadTile(absQuadCoords - objToCheck.MapCoords) != null) { retList.Add(relQuadCoords); } } } } return(retList); }
/// <see cref="ITerrainObjectConstraint.Check"/> public RCSet <RCIntVector> Check(IMapAccess map, RCIntVector position) { if (map == null) { throw new ArgumentNullException("map"); } if (position == RCIntVector.Undefined) { throw new ArgumentNullException("position"); } RCSet <RCIntVector> retList = new RCSet <RCIntVector>(); RCIntVector absQuadCoords = position + this.quadCoords; if (absQuadCoords.X >= 0 && absQuadCoords.X < map.Size.X && absQuadCoords.Y >= 0 && absQuadCoords.Y < map.Size.Y) { IQuadTile checkedQuadTile = map.GetQuadTile(absQuadCoords); IIsoTile checkedIsoTile = checkedQuadTile.PrimaryIsoTile; if (checkedIsoTile.Type.TerrainA != this.terrainA || checkedIsoTile.Type.TerrainB != this.terrainB || !this.allowedCombinations.Contains(checkedIsoTile.Type.Combination)) { retList.Add(this.quadCoords); foreach (IQuadTile neighbour in checkedQuadTile.Neighbours) { if (neighbour.PrimaryIsoTile == checkedIsoTile) { retList.Add(neighbour.MapCoords - position); } } } } return(retList); }
/// <see cref="IMapLoader.SaveMap"/> public byte[] SaveMap(IMapAccess map) { if (!this.initThreadStarted) { throw new InvalidOperationException("Component has not yet been started!"); } this.initThread.Join(); if (map == null) { throw new ArgumentNullException("map"); } RCPackage mapHeader = this.CreateMapHeaderPackage(map); RCPackage isotileList = this.CreateIsoTileListPackage(map); RCPackage terrainObjList = this.CreateTerrainObjListPackage(map); byte[] retArray = new byte[mapHeader.PackageLength + isotileList.PackageLength + terrainObjList.PackageLength]; int offset = 0; offset += mapHeader.WritePackageToBuffer(retArray, offset); offset += isotileList.WritePackageToBuffer(retArray, offset); offset += terrainObjList.WritePackageToBuffer(retArray, offset); return(retArray); }
/// <see cref="IScenarioManagerBC.OpenScenario"/> public void OpenScenario(string filename) { if (this.activeScenario != null) { throw new InvalidOperationException("Another scenario is currently active!"); } if (filename == null) { throw new ArgumentNullException("fileName"); } byte[] mapBytes = File.ReadAllBytes(filename); MapHeader mapHeader = this.mapLoader.LoadMapHeader(mapBytes); IMapAccess map = this.mapLoader.LoadMap(this.tilesetManager.GetTileSet(mapHeader.TilesetName), mapBytes); this.pathfinder.Initialize(new MapWalkabilityReader(map), MAX_MOVING_ENTITY_SIZE); this.activeScenario = this.scenarioLoader.LoadScenario(map, mapBytes); this.RegisterFactoryMethods(); if (this.ActiveScenarioChanged != null) { this.ActiveScenarioChanged(this.activeScenario); } }
/// <see cref="IScenarioLoader.LoadScenario"/> public Scenario LoadScenario(IMapAccess map, byte[] data) { if (map == null) { throw new ArgumentNullException("map"); } if (data == null) { throw new ArgumentNullException("data"); } /// Load the packages from the byte array. int offset = 0; Scenario scenario = new Scenario(map); while (offset < data.Length) { int parsedBytes; RCPackage package = RCPackage.Parse(data, offset, data.Length - offset, out parsedBytes); if (package == null || !package.IsCommitted) { throw new SimulatorException("Syntax error!"); } offset += parsedBytes; if (package.PackageFormat.ID == ScenarioFileFormat.MINERAL_FIELD) { IQuadTile quadTile = map.GetQuadTile(new RCIntVector(package.ReadShort(0), package.ReadShort(1))); MineralField mineralField = new MineralField(); mineralField.ResourceAmount.Write(package.ReadInt(2)); scenario.AddElementToScenario(mineralField); mineralField.AttachToMap(quadTile); } else if (package.PackageFormat.ID == ScenarioFileFormat.VESPENE_GEYSER) { IQuadTile quadTile = map.GetQuadTile(new RCIntVector(package.ReadShort(0), package.ReadShort(1))); VespeneGeyser vespeneGeyser = new VespeneGeyser(); vespeneGeyser.ResourceAmount.Write(package.ReadInt(2)); scenario.AddElementToScenario(vespeneGeyser); vespeneGeyser.AttachToMap(quadTile); } else if (package.PackageFormat.ID == ScenarioFileFormat.START_LOCATION) { IQuadTile quadTile = map.GetQuadTile(new RCIntVector(package.ReadShort(0), package.ReadShort(1))); StartLocation startLocation = new StartLocation(package.ReadByte(2)); scenario.AddElementToScenario(startLocation); startLocation.AttachToMap(quadTile); } } /// Check the constraints of the visible entities. foreach (Entity entity in scenario.GetElementsOnMap <Entity>(MapObjectLayerEnum.GroundObjects, MapObjectLayerEnum.AirObjects)) { if (entity.CheckPlacementConstraints(entity.MapObject.QuadraticPosition.Location, new RCSet <Entity>()).Count != 0) { throw new MapException(string.Format("Entity at {0} is voilating its placement constraints!", entity.MapObject.QuadraticPosition.Location)); } } return(scenario); }
/// <summary> /// Constructs a walkability reader instance for the given map. /// </summary> /// <param name="map">The map to read.</param> public MapWalkabilityReader(IMapAccess map) { if (map == null) { throw new ArgumentNullException("map"); } this.map = map; }
/// <see cref="IScenarioLoader.NewScenario"/> public Scenario NewScenario(IMapAccess map) { if (map == null) { throw new ArgumentNullException("map"); } return(new Scenario(map)); }
/// <summary> /// Creates the package that contains the description of the isometric tiles of the given map. /// </summary> /// <param name="map">Reference to the map.</param> /// <returns>The data package that contains the description of the isometric tiles of the given map.</returns> private RCPackage CreateIsoTileListPackage(IMapAccess map) { RCPackage isotileList = RCPackage.CreateCustomDataPackage(MapFileFormat.ISOTILE_LIST); /// Create the terrain type index table. List <string> terrainTypeList = new List <string>(); Dictionary <ITerrainType, int> terrainTypeIndexTable = new Dictionary <ITerrainType, int>(); int terrainTypeIndex = 0; foreach (ITerrainType terrainType in map.Tileset.TerrainTypes) { terrainTypeList.Add(terrainType.Name); terrainTypeIndexTable.Add(terrainType, terrainTypeIndex); terrainTypeIndex++; } isotileList.WriteStringArray(0, terrainTypeList.ToArray()); /// Create the packages of the isometric tiles. RCSet <IIsoTile> processedIsoTiles = new RCSet <IIsoTile>(); List <RCPackage> isotilePackages = new List <RCPackage>(); int isotileInfoLength = 0; for (int row = 0; row < map.Size.Y; row++) { for (int column = 0; column < map.Size.X; column++) { IIsoTile currIsoTile = map.GetQuadTile(new RCIntVector(column, row)).PrimaryIsoTile; if (!processedIsoTiles.Contains(currIsoTile)) { RCPackage isotilePackage = RCPackage.CreateCustomDataPackage(MapFileFormat.ISOTILE); isotilePackage.WriteShort(0, (short)column); isotilePackage.WriteShort(1, (short)row); isotilePackage.WriteByte(2, (byte)terrainTypeIndexTable[currIsoTile.Type.TerrainA]); isotilePackage.WriteByte(3, currIsoTile.Type.TerrainB != null ? (byte)terrainTypeIndexTable[currIsoTile.Type.TerrainB] : (byte)0); isotilePackage.WriteByte(4, (byte)currIsoTile.Type.Combination); isotilePackage.WriteByte(5, (byte)currIsoTile.VariantIdx); isotilePackages.Add(isotilePackage); processedIsoTiles.Add(currIsoTile); isotileInfoLength += isotilePackage.PackageLength; } } } /// Write the isometric tile packages into the final package byte[] isotileInfoBytes = new byte[isotileInfoLength]; int offset = 0; foreach (RCPackage isotilePackage in isotilePackages) { offset += isotilePackage.WritePackageToBuffer(isotileInfoBytes, offset); } isotileList.WriteByteArray(1, isotileInfoBytes); return(isotileList); }
/// <summary> /// Initializes the terrain objects of the map. /// </summary> /// <param name="terrainObjListPackage">The package that contains the terrain object informations.</param> /// <param name="map">Reference to the map.</param> private void LoadTerrainObjects(RCPackage terrainObjListPackage, IMapAccess map) { /// TODO: Avoid this downcast! MapAccess mapObj = map as MapAccess; if (mapObj == null) { throw new ArgumentException("The given map cannot be handled by the MapEditor!", "map"); } string[] terrainObjIndexTable = terrainObjListPackage.ReadStringArray(0); byte[] terrainObjInfoBytes = terrainObjListPackage.ReadByteArray(1); int offset = 0; while (offset < terrainObjInfoBytes.Length) { int parsedBytes; RCPackage package = RCPackage.Parse(terrainObjInfoBytes, offset, terrainObjInfoBytes.Length - offset, out parsedBytes); if (package == null || !package.IsCommitted) { throw new MapException("Syntax error!"); } offset += parsedBytes; if (package.PackageFormat.ID == MapFileFormat.TERRAINOBJ) { RCIntVector quadCoords = new RCIntVector(package.ReadShort(0), package.ReadShort(1)); ITerrainObjectType terrainObjType = this.mapStructure.Tileset.GetTerrainObjectType(terrainObjIndexTable[package.ReadByte(2)]); /// TODO: Might be better to create the TerrainObject with a factory? ITerrainObject newObj = new TerrainObject(map, terrainObjType, quadCoords); foreach (ICellDataChangeSet changeset in newObj.Type.CellDataChangesets) { changeset.Apply(newObj); } mapObj.AttachTerrainObject(newObj); } } /// Check the constraints of the terrain objects. List <ITerrainObject> terrainObjects = new List <ITerrainObject>(map.TerrainObjects); foreach (ITerrainObject terrainObj in terrainObjects) { mapObj.DetachTerrainObject(terrainObj); if (terrainObj.Type.CheckConstraints(map, terrainObj.MapCoords).Count != 0) { throw new MapException(string.Format("Terrain object at {0} is voilating the tileset constraints!", terrainObj.MapCoords)); } if (terrainObj.Type.CheckTerrainObjectIntersections(map, terrainObj.MapCoords).Count != 0) { throw new MapException(string.Format("Terrain object at {0} intersects other terrain objects!", terrainObj.MapCoords)); } mapObj.AttachTerrainObject(terrainObj); } }
IEnumerator Start() { LoadingCanvas.gameObject.SetActive(true); ShowPlayerName(false); HumanPlayerController.CanShoot = false; ControlsText.gameObject.SetActive(GameProgressData.CurrentProgress.NumberOfDeaths == 0); while (!PlayFabFacade.Instance.LoginProcessComplete) { yield return(null); } Weapons.LoadWeaponsFromResources(); Enemies.LoadEnemiesFromResources(); QuestPortal.SetActive(false); LoadingCanvas.gameObject.SetActive(false); IntroCanvas.gameObject.SetActive(true); string ghostPath = PlayerPrefs.GetString("LatestCampPath"); try { if (string.IsNullOrWhiteSpace(ghostPath)) { PlayFabFacade.AllData.InfoResultPayload.TitleData.TryGetValue("DefaultCampGhost", out ghostPath); } GhostPath.FromString(ghostPath); if (GhostPath.HasPath) { var ghost = Instantiate(GhostPlayerPrefab, Vector3.left * 10000, Quaternion.identity); ghostScript_ = ghost.GetComponent <GhostPlayerScript>(); } } catch (System.Exception) { } camPos_ = SceneGlobals.Instance.CameraPositioner; camShake_ = SceneGlobals.Instance.CameraShake; lightingImageEffect_ = SceneGlobals.Instance.LightingImageEffect; mapAccess_ = SceneGlobals.Instance.MapAccess; mapScript_ = SceneGlobals.Instance.MapScript; lightingImageEffect_.Darkness = 0.0f; SceneGlobals.Instance.GraveStoneManager.CreateGravestones(); mapAccess_.BuildCollisionMapFromWallTilemap(mapScript_.FloorTileMap); SetLighting(MenuLightingSettings); CreateCharacters(); ActivateLatestSelectedCharacter(); StartCoroutine(InMenu()); }
/// <summary> /// Implements visibility calculations when there is no running FogOfWars. /// </summary> /// <returns>The results of the visibility calculations.</returns> private FowVisibilityInfo CalculateVisibilityWithoutFow() { /// Collect the isometric & quadratic tiles that need to be updated. IMapAccess map = this.ActiveScenario.Map; RCSet <IIsoTile> isoTilesToUpdate = new RCSet <IIsoTile>(); RCSet <ITerrainObject> terrainObjectsToUpdate = new RCSet <ITerrainObject>(); for (int column = this.quadTileWindow.Left; column < this.quadTileWindow.Right; column++) { for (int row = this.quadTileWindow.Top; row < this.quadTileWindow.Bottom; row++) { /// Add the primary & secondary isometric tiles into the update lists. IQuadTile quadTileToUpdate = map.GetQuadTile(new RCIntVector(column, row)); if (quadTileToUpdate.PrimaryIsoTile != null) { isoTilesToUpdate.Add(quadTileToUpdate.PrimaryIsoTile); } if (quadTileToUpdate.SecondaryIsoTile != null) { isoTilesToUpdate.Add(quadTileToUpdate.SecondaryIsoTile); } if (quadTileToUpdate.TerrainObject != null) { terrainObjectsToUpdate.Add(quadTileToUpdate.TerrainObject); } } } /// Collect the currently visible map objects on the ground. RCSet <MapObject> groundMapObjectsToUpdate = this.ActiveScenario.GetMapObjects( this.mapWindowBC.AttachedWindow.WindowMapCoords, MapObjectLayerEnum.GroundObjects, MapObjectLayerEnum.GroundMissiles); /// Collect the currently visible map objects in the air. RCSet <MapObject> airMapObjectsToUpdate = this.ActiveScenario.GetMapObjects( this.mapWindowBC.AttachedWindow.WindowMapCoords, MapObjectLayerEnum.AirObjects, MapObjectLayerEnum.AirMissiles); /// Create the calculated visibility info. return(new FowVisibilityInfo { IsoTilesToUpdate = isoTilesToUpdate, TerrainObjectsToUpdate = terrainObjectsToUpdate, QuadTilesToUpdate = new List <IQuadTile>(), EntitySnapshotsToUpdate = new List <EntitySnapshot>(), GroundMapObjectsToUpdate = groundMapObjectsToUpdate, AirMapObjectsToUpdate = airMapObjectsToUpdate }); }
/// <summary> /// Constructs a terrain object. /// </summary> /// <param name="map">The map that this terrain object belongs to.</param> /// <param name="type">The type of this terrain object.</param> /// <param name="mapCoords">The coordinates of the top-left quadratic tile of this terrain object.</param> public TerrainObject(IMapAccess map, ITerrainObjectType type, RCIntVector mapCoords) { if (map == null) { throw new ArgumentNullException("map"); } if (type == null) { throw new ArgumentNullException("type"); } if (mapCoords == RCIntVector.Undefined) { throw new ArgumentNullException("type"); } if (type.Tileset != map.Tileset) { throw new MapException("Tileset of the TerrainObjectType and tileset of the map are not the same!"); } this.mapCoords = mapCoords; this.type = type; this.parentMap = map; this.cells = new Cell[this.type.QuadraticSize.X * MapStructure.NAVCELL_PER_QUAD, this.type.QuadraticSize.Y * MapStructure.NAVCELL_PER_QUAD]; this.quadTiles = new QuadTile[this.type.QuadraticSize.X, this.type.QuadraticSize.Y]; /// Set the references to the appropriate quadratic tiles and cells. for (int quadX = 0; quadX < this.type.QuadraticSize.X; quadX++) { for (int quadY = 0; quadY < this.type.QuadraticSize.Y; quadY++) { RCIntVector relQuadCoords = new RCIntVector(quadX, quadY); if (!this.type.IsExcluded(relQuadCoords)) { IQuadTile currQuadTile = this.parentMap.GetQuadTile(this.mapCoords + relQuadCoords); this.quadTiles[quadX, quadY] = currQuadTile; for (int navX = 0; navX < MapStructure.NAVCELL_PER_QUAD; navX++) { for (int navY = 0; navY < MapStructure.NAVCELL_PER_QUAD; navY++) { RCIntVector relNavCoords = relQuadCoords * MapStructure.NAVCELL_PER_QUAD + new RCIntVector(navX, navY); this.cells[relNavCoords.X, relNavCoords.Y] = currQuadTile.GetCell(new RCIntVector(navX, navY)); } } } } } /// TODO: Apply the cell data changesets! /// TODO: Attach this TerrainObject to the map! }
/// <see cref="IScenarioManagerBC.CloseScenario"/> public void CloseScenario() { if (this.activeScenario != null) { this.UnregisterFactoryMethods(); IMapAccess map = this.activeScenario.Map; this.activeScenario.Dispose(); map.Close(); this.activeScenario = null; if (this.ActiveScenarioChanged != null) { this.ActiveScenarioChanged(this.activeScenario); } } }
/// <see cref="IMapEditor.PlaceTerrainObject"/> public ITerrainObject PlaceTerrainObject(IMapAccess targetMap, IQuadTile targetTile, ITerrainObjectType type) { if (targetMap == null) { throw new ArgumentNullException("targetMap"); } if (targetTile == null) { throw new ArgumentNullException("targetTile"); } if (type == null) { throw new ArgumentNullException("type"); } if (targetMap.Tileset != type.Tileset) { throw new InvalidOperationException("The tileset of the terrain object type must be the same as the tileset of the map!"); } /// TODO: Avoid this downcast! MapAccess targetMapObj = targetMap as MapAccess; if (targetMapObj == null) { throw new ArgumentException("The given map cannot be handled by the MapEditor!", "targetMap"); } if (type.CheckConstraints(targetMap, targetTile.MapCoords).Count != 0) { return(null); } if (type.CheckTerrainObjectIntersections(targetMap, targetTile.MapCoords).Count != 0) { return(null); } /// TODO: Might be better to create the TerrainObject with a factory? ITerrainObject newObj = new TerrainObject(targetMap, type, targetTile.MapCoords); foreach (ICellDataChangeSet changeset in newObj.Type.CellDataChangesets) { changeset.Apply(newObj); } targetMapObj.AttachTerrainObject(newObj); return(newObj); }
/// <summary> /// Creates the header package of the given map. /// </summary> /// <param name="map">Reference to the map.</param> /// <returns>The data package that contains the header of the given map.</returns> private RCPackage CreateMapHeaderPackage(IMapAccess map) { RCPackage mapHeader = RCPackage.CreateCustomDataPackage(MapFileFormat.MAP_HEADER); Version appVersion = new Version(ConstantsTable.Get <string>("RC.App.Version")); mapHeader.WriteInt(0, appVersion.Major); mapHeader.WriteInt(1, appVersion.Minor); mapHeader.WriteInt(2, appVersion.Build); mapHeader.WriteInt(3, appVersion.Revision); mapHeader.WriteString(4, map.MapName); mapHeader.WriteString(5, map.Tileset.Name); mapHeader.WriteShort(6, (short)map.Size.X); mapHeader.WriteShort(7, (short)map.Size.Y); mapHeader.WriteByte(8, (byte)8); // TODO: get the maximum number of players mapHeader.WriteIntArray(9, new int[0] { }); // TODO: get checksum values of the map return(mapHeader); }
/// <see cref="IScenarioManagerBC.NewScenario"/> public void NewScenario(string mapName, string tilesetName, string defaultTerrain, Common.RCIntVector mapSize) { if (this.activeScenario != null) { throw new InvalidOperationException("Another scenario is currently active!"); } IMapAccess map = this.mapLoader.NewMap(mapName, this.tilesetManager.GetTileSet(tilesetName), defaultTerrain, mapSize); this.activeScenario = this.scenarioLoader.NewScenario(map); this.RegisterFactoryMethods(); if (this.ActiveScenarioChanged != null) { this.ActiveScenarioChanged(this.activeScenario); } }
/// <summary> /// Creates the package that contains the description of the terrain objects of the given map. /// </summary> /// <param name="map">Reference to the map.</param> /// <returns>The data package that contains the description of the terrain objects of the given map.</returns> private RCPackage CreateTerrainObjListPackage(IMapAccess map) { RCPackage terrainObjList = RCPackage.CreateCustomDataPackage(MapFileFormat.TERRAINOBJ_LIST); /// Create the terrain object type index table. List <string> terrainObjTypeList = new List <string>(); Dictionary <ITerrainObjectType, int> terrainObjTypeIndexTable = new Dictionary <ITerrainObjectType, int>(); int terrainObjTypeIndex = 0; foreach (ITerrainObjectType terrainObjType in map.Tileset.TerrainObjectTypes) { terrainObjTypeList.Add(terrainObjType.Name); terrainObjTypeIndexTable.Add(terrainObjType, terrainObjTypeIndex); terrainObjTypeIndex++; } terrainObjList.WriteStringArray(0, terrainObjTypeList.ToArray()); /// Create the packages of the terrain objects. List <RCPackage> terrainObjPackages = new List <RCPackage>(); int terrainObjInfoLength = 0; foreach (ITerrainObject terrainObj in map.TerrainObjects) { RCPackage terrainObjPackage = RCPackage.CreateCustomDataPackage(MapFileFormat.TERRAINOBJ); terrainObjPackage.WriteShort(0, (short)terrainObj.MapCoords.X); terrainObjPackage.WriteShort(1, (short)terrainObj.MapCoords.Y); terrainObjPackage.WriteByte(2, (byte)terrainObjTypeIndexTable[terrainObj.Type]); terrainObjPackages.Add(terrainObjPackage); terrainObjInfoLength += terrainObjPackage.PackageLength; } /// Write the terrain object packages into the final package byte[] terrainObjInfoBytes = new byte[terrainObjInfoLength]; int offset = 0; foreach (RCPackage terrainObjPackage in terrainObjPackages) { offset += terrainObjPackage.WritePackageToBuffer(terrainObjInfoBytes, offset); } terrainObjList.WriteByteArray(1, terrainObjInfoBytes); return(terrainObjList); }
void Awake() { transform_ = transform; body_ = GetComponent <Rigidbody2D>(); map_ = SceneGlobals.Instance.MapAccess; spriteAnimator_ = GetComponentInChildren <ISpriteAnimator>(); renderMaterial_ = SpriteRenderer.material; collider_ = GetComponent <Collider2D>(); aiPath_ = GetComponent <AIPath>(); BlipRenderer.enabled = true; mapLayer_ = SceneGlobals.Instance.MapLayer; mapLayerMask_ = 1 << SceneGlobals.Instance.MapLayer; playerLayer_ = SceneGlobals.Instance.PlayerLayer; speedVariation_ = 1.0f - ((Random.value * SpeedVariation) - SpeedVariation * 0.5f); MaxLife = EnemyLife; spriteTransform_ = SpriteRenderer.transform; spriteOffsetX_ = spriteTransform_.localPosition.x; }
/// <see cref="IBuildingTypeInternal.GetRelativeAddonPosition"/> public RCIntVector GetRelativeAddonPosition(IMapAccess map, IAddonTypeInternal addonType) { if (map == null) { throw new ArgumentNullException("map"); } if (addonType == null) { throw new ArgumentNullException("addonType"); } if (!this.HasAddonType(addonType.Name)) { throw new ArgumentException(string.Format("Building type '{0}' is not defined as the main building for addon type '{1}'!", this.Name, addonType.Name)); } RCIntVector buildingQuadSize = map.CellToQuadSize(this.Area.Read().Size); int addonQuadHeight = map.CellToQuadSize(addonType.Area.Read().Size).Y; return(new RCIntVector(buildingQuadSize.X, buildingQuadSize.Y - addonQuadHeight)); }
/// <summary> /// Constructs a Scenario instance. /// </summary> /// <param name="map">The map of the scenario.</param> /// <param name="initializers">The registered star location initializers.</param> internal Scenario(IMapAccess map) { if (map == null) { throw new ArgumentNullException("map"); } /// Create the heaped members. this.nextID = this.ConstructField <int>("nextID"); this.currentFrameIndex = this.ConstructField <int>("currentFrameIndex"); this.playersFinalized = this.ConstructField <byte>("playersFinalized"); this.players = this.ConstructArrayField <Player>("players"); /// Initialize the heaped members. this.nextID.Write(0); this.currentFrameIndex.Write(0); this.playersFinalized.Write(0x00); this.players.New(Player.MAX_PLAYERS); /// Initialize the non-heaped members. this.map = map; this.elementFactory = ComponentManager.GetInterface <IElementFactory>(); this.mapObjects = new Dictionary <MapObjectLayerEnum, ISearchTree <MapObject> > { { MapObjectLayerEnum.GroundObjects, this.CreateSearchTree() }, { MapObjectLayerEnum.GroundMissiles, this.CreateSearchTree() }, { MapObjectLayerEnum.AirObjects, this.CreateSearchTree() }, { MapObjectLayerEnum.AirMissiles, this.CreateSearchTree() } }; this.idToScenarioElementMap = new Dictionary <int, ScenarioElement>(); this.scenarioElements = new RCSet <ScenarioElement>(); this.elementsToAddAfterUpdate = new RCSet <ScenarioElement>(); this.elementsToRemoveAfterUpdate = new RCSet <ScenarioElement>(); this.fixedEntities = new Entity[this.map.Size.X, this.map.Size.Y]; this.commandExecutions = new RCSet <CmdExecutionBase>(); this.addRemoveElementForbidden = false; this.updateInProgress = false; }
void Awake() { MapLayer = LayerMask.NameToLayer("Map"); PlayerLayer = LayerMask.NameToLayer("Player"); PlayerDamageLayer = LayerMask.NameToLayer("PlayerDamage"); PlayerInteractionLayer = LayerMask.NameToLayer("PlayerInteraction"); EnemyLayer = LayerMask.NameToLayer("Enemy"); EnemyNoWallsLayer = LayerMask.NameToLayer("EnemyNoWalls"); EnemyDamageLayer = LayerMask.NameToLayer("EnemyDamage"); DeadEnemyLayer = LayerMask.NameToLayer("DeadEnemy"); EnemyDeadOrAliveMask = (1 << EnemyLayer) + (1 << EnemyNoWallsLayer) + (1 << DeadEnemyLayer); EnemyAliveMask = (1 << EnemyLayer) + (1 << EnemyNoWallsLayer); CameraPositioner = FindObjectOfType <CameraPositioner>(); CameraShake = FindObjectOfType <CameraShake>(); AudioManager = FindObjectOfType <AudioManager>(); MapScript = FindObjectOfType <MapScript>(); MapAccess = (IMapAccess)MapScript; ParticleScript = FindObjectOfType <ParticleScript>(); DebugLinesScript = FindObjectOfType <DebugLinesScript>(); LightingImageEffect = FindObjectOfType <LightingImageEffect>(); LightingCamera = FindObjectOfType <LightingCamera>(); MapCamera = FindObjectOfType <MiniMapCamera>(); PlayableCharacters = FindObjectOfType <PlayableCharacters>(); GraveStoneManager = FindObjectOfType <GraveStoneManager>(); NullCheck(MapLayer); NullCheck(PlayerLayer); NullCheck(PlayerDamageLayer); NullCheck(PlayerInteractionLayer); NullCheck(EnemyLayer); NullCheck(EnemyDamageLayer); NullCheck(DeadEnemyLayer); Instance = this; }
/// <see cref="ITerrainObjectType.CheckConstraints"/> public RCSet <RCIntVector> CheckConstraints(IMapAccess map, RCIntVector position) { if (map == null) { throw new ArgumentNullException("map"); } if (position == RCIntVector.Undefined) { throw new ArgumentNullException("position"); } /// Check against the constraints defined by this terrain object type. RCSet <RCIntVector> retList = new RCSet <RCIntVector>(); foreach (ITerrainObjectConstraint contraint in this.constraints) { retList.UnionWith(contraint.Check(map, position)); } for (int quadX = 0; quadX < this.quadraticSize.X; quadX++) { for (int quadY = 0; quadY < this.quadraticSize.Y; quadY++) { RCIntVector relQuadCoords = new RCIntVector(quadX, quadY); RCIntVector absQuadCoords = position + relQuadCoords; if (absQuadCoords.X < 0 || absQuadCoords.X >= map.Size.X || absQuadCoords.Y < 0 || absQuadCoords.Y >= map.Size.Y) { /// Intersection with the boundaries of the map. retList.Add(relQuadCoords); } } } return(retList); }
/// <summary> /// Fills up the layers from the base layer up to the target layer. /// </summary> /// <param name="center">The center of the draw operation.</param> /// <param name="targetTerrain">The target terrain of the draw operation.</param> /// <param name="baseTerrain">The base layer of the draw operation.</param> public void FillLayers(IMapAccess map, IIsoTile center, ITerrainType targetTerrain, ITerrainType baseTerrain) { /// Find the biggest flood area to be filled. FloodArea areaToFill = new FloodArea(); ITerrainType[] layersToFill = targetTerrain.FindRoute(baseTerrain); for (int routeIdx = 0; routeIdx < layersToFill.Length; routeIdx++) { ITerrainType prevTerrain = routeIdx - 1 >= 0 ? layersToFill[routeIdx - 1] : null; if (prevTerrain != null) { areaToFill.Enlarge(prevTerrain.TransitionLength + 1); } } /// Fill the appropriate layers for (int routeIdx = layersToFill.Length - 1; routeIdx >= 0; routeIdx--) { /// Fill the current layer at the appropriate area. ITerrainType currLayer = layersToFill[routeIdx]; foreach (FloodItem floodItem in areaToFill) { IIsoTile filledTile = map.GetIsoTile(center.MapCoords + floodItem.Coordinates); if (filledTile != null) { if (filledTile.Type.Combination != TerrainCombination.Simple) { /// Mixed tile. if (filledTile.Type.TerrainB == currLayer) { int newCombInt = (int)filledTile.Type.Combination | (floodItem.Combination != TerrainCombination.Simple ? (int)floodItem.Combination : 0xF); TerrainCombination newComb = newCombInt != 0xF ? (TerrainCombination)newCombInt : TerrainCombination.Simple; if (newComb != filledTile.Type.Combination) { filledTile.ExchangeType( newComb == TerrainCombination.Simple ? map.Tileset.GetIsoTileType(filledTile.Type.TerrainB.Name) : map.Tileset.GetIsoTileType(filledTile.Type.TerrainA.Name, filledTile.Type.TerrainB.Name, newComb)); } } else if (currLayer.IsDescendantOf(filledTile.Type.TerrainB)) { throw new MapException("Filling over the topmost layer is not possible!"); } } else { /// Simple tile. if (filledTile.Type.TerrainA == currLayer.Parent) { filledTile.ExchangeType( floodItem.Combination == TerrainCombination.Simple ? map.Tileset.GetIsoTileType(currLayer.Name) : map.Tileset.GetIsoTileType(filledTile.Type.TerrainA.Name, currLayer.Name, floodItem.Combination)); } else if (currLayer.IsDescendantOf(filledTile.Type.TerrainA)) { throw new MapException("Filling over the topmost layer is not possible!"); } } } } if (routeIdx > 0) { areaToFill.Reduce(); } } }
/// <summary> /// Clears the given layers for a draw operation. /// </summary> /// <param name="map">Reference to the map.</param> /// <param name="center">The center of the draw operation.</param> /// <param name="targetTerrain">The target terrain of the draw operation.</param> /// <param name="baseTerrain">The base layer of the draw operation.</param> /// <param name="layersToClear">The route from the target terrain up to a topmost layer in the terrain tree.</param> private void ClearLayers(IMapAccess map, IIsoTile center, ITerrainType targetTerrain, ITerrainType baseTerrain, ITerrainType[] layersToClear) { /// Find the biggest flood area to be cleared. FloodArea areaToClear = new FloodArea(); ITerrainType lastUninjuredLayer = null; for (int routeIdx = 0; routeIdx < layersToClear.Length; routeIdx++) { ITerrainType currTerrain = layersToClear[routeIdx]; if (lastUninjuredLayer == null) { /// We are going downstairs. ITerrainType nextTerrain = layersToClear[routeIdx + 1]; if (nextTerrain.Parent == currTerrain) { /// Last uninjured layer found, from now we go upstairs. lastUninjuredLayer = currTerrain; /// Enlarge the clear area by 1 if there was a previous layer along the way downstairs. ITerrainType prevTerrain = routeIdx - 1 >= 0 ? layersToClear[routeIdx - 1] : null; if (prevTerrain != null) { areaToClear.Enlarge(1); } } else { /// Enlarge the clear area by the transition length of the previous layer if there /// was a previous layer along the way downstairs. ITerrainType prevTerrain = routeIdx - 1 >= 0 ? layersToClear[routeIdx - 1] : null; if (prevTerrain != null) { areaToClear.Enlarge(prevTerrain.TransitionLength + 1); } } } else { /// We are going upstairs. ITerrainType prevTerrain = layersToClear[routeIdx - 1]; if (prevTerrain != lastUninjuredLayer) { areaToClear.Enlarge(currTerrain.TransitionLength + 1); } } } /// Clear the appropriate layers. if (lastUninjuredLayer == null) { throw new MapException("Last uninjured layer not found for draw terrain operation!"); } for (int routeIdx = layersToClear.Length - 1; routeIdx >= 0; routeIdx--) { ITerrainType currLayer = layersToClear[routeIdx]; if (currLayer == lastUninjuredLayer) { break; } /// Clear the current layer at the appropriate area. foreach (FloodItem floodItem in areaToClear) { IIsoTile clearedTile = map.GetIsoTile(center.MapCoords + floodItem.Coordinates); if (clearedTile != null) { if (clearedTile.Type.Combination != TerrainCombination.Simple) { /// Mixed tile. if (clearedTile.Type.TerrainB.IsDescendantOf(currLayer)) { /// Check whether TerrainB will be cleared by another branch or this is an error. if (!layersToClear.Contains(clearedTile.Type.TerrainB)) { continue; } else { throw new MapException("Clearing non-topmost layer is not possible!"); } } if (clearedTile.Type.TerrainB == currLayer) { TerrainCombination newComb = (TerrainCombination)((int)clearedTile.Type.Combination & ~(floodItem.Combination != TerrainCombination.Simple ? (int)floodItem.Combination : 0xF)); if (newComb != clearedTile.Type.Combination) { clearedTile.ExchangeType( newComb == TerrainCombination.Simple ? map.Tileset.GetIsoTileType(clearedTile.Type.TerrainA.Name) : map.Tileset.GetIsoTileType(clearedTile.Type.TerrainA.Name, clearedTile.Type.TerrainB.Name, newComb)); } } } else { /// Simple tile. if (clearedTile.Type.TerrainA.IsDescendantOf(currLayer)) { /// Check whether TerrainA will be cleared by another branch or this is an error. if (!layersToClear.Contains(clearedTile.Type.TerrainA)) { continue; } else { throw new MapException("Clearing non-topmost layer is not possible!"); } } if (clearedTile.Type.TerrainA == currLayer) { TerrainCombination newComb = (TerrainCombination)(0xF & ~(floodItem.Combination != TerrainCombination.Simple ? (int)floodItem.Combination : 0xF)); clearedTile.ExchangeType( newComb == TerrainCombination.Simple ? map.Tileset.GetIsoTileType(clearedTile.Type.TerrainA.Parent.Name) : map.Tileset.GetIsoTileType(clearedTile.Type.TerrainA.Parent.Name, clearedTile.Type.TerrainA.Name, newComb)); } } } } if (routeIdx > 1) { areaToClear.Reduce(); } } }
/// <see cref="IMapEditor.DrawTerrain"/> public IEnumerable <IIsoTile> DrawTerrain(IMapAccess targetMap, IIsoTile targetTile, ITerrainType terrainType) { if (targetMap == null) { throw new ArgumentNullException("targetMap"); } if (targetTile == null) { throw new ArgumentNullException("targetTile"); } if (terrainType == null) { throw new ArgumentNullException("terrainType"); } if (targetMap.Tileset != terrainType.Tileset) { throw new InvalidOperationException("The tileset of the new terrain type must be the same as the tileset of the map!"); } /// Notify the map that the tile exchanging procedure is started. targetMap.BeginExchangingTiles(); /// First we have to search the basis layer of the draw operation. ITerrainType baseLayer = terrainType; FloodArea floodArea = new FloodArea(); while (!this.CheckLayer(targetMap, targetTile, baseLayer, floodArea)) { floodArea.Enlarge(baseLayer.TransitionLength + 1); baseLayer = baseLayer.Parent; if (baseLayer == null) { throw new MapException("Basis-layer not found for draw terrain operation!"); } } /// Clear the appropriate areas of the map around the target tile of the draw operation. foreach (ITerrainType topmostLayer in targetMap.Tileset.TerrainTypes) { if (topmostLayer.IsDescendantOf(baseLayer) && topmostLayer != terrainType && !topmostLayer.HasChildren) { ITerrainType[] layersToClear = terrainType.FindRoute(topmostLayer); this.ClearLayers(targetMap, targetTile, terrainType, baseLayer, layersToClear); } } /// Fill the appropriate areas of the map around the target tile of the draw operation. this.FillLayers(targetMap, targetTile, terrainType, baseLayer); /// Force regenerating the variant of the draw operation center and its neighbours. targetTile.ExchangeType(targetTile.Type); /// Remove the terrain objects that are violating the new map terrain. IEnumerable <IIsoTile> affectedIsoTiles = targetMap.EndExchangingTiles(); foreach (IIsoTile affectedIsoTile in affectedIsoTiles) { foreach (IQuadTile cuttingQuadTile in affectedIsoTile.CuttingQuadTiles) { ITerrainObject affectedTerrainObj = cuttingQuadTile.TerrainObject; if (affectedTerrainObj != null && affectedTerrainObj.Type.CheckConstraints(targetMap, affectedTerrainObj.MapCoords).Count != 0) { this.RemoveTerrainObject(targetMap, affectedTerrainObj); } } } return(affectedIsoTiles); }
/// <summary> /// Gets the quadratic position of the given addon type relative to the top-left quadratic tile of this building type. /// </summary> /// <param name="map">The map that is used for the calculations.</param> /// <param name="addonType">The addon type whose relative quadratic position to retrieve.</param> /// <returns>The quadratic position of the given addon type relative to the top-left quadratic tile of this building type.</returns> /// <exception cref="ArgumentException"> /// If this building type is not defined as the main building for the given addon type. /// </exception> public RCIntVector GetRelativeAddonPosition(IMapAccess map, IAddonType addonType) { return(this.implementation.GetRelativeAddonPosition(map, addonType.AddonTypeImpl)); }
/// <summary> /// Constructs a CellIteratorBase instance. /// </summary> /// <param name="map">The map whose cells need to be visited.</param> protected CellIteratorBase(IMapAccess map) { if (map == null) { throw new ArgumentNullException("map"); } this.map = map; }
/// <see cref="IBuildingTypeInternal.GetRelativeAddonPosition"/> RCIntVector IBuildingTypeInternal.GetRelativeAddonPosition(IMapAccess map, IAddonTypeInternal addonType) { return(this.originalBuildingType.GetRelativeAddonPosition(map, addonType)); }