/** * Adds a new monster to the game. * @param instance the monster instance to add * @param area, the area this monster is associated with. * @param location, the location this monster should be spawned at. */ public void AddMonster(MDRMonsterInstance instance, MDRArea area = null, MDRLocation?location = null) { if (instance == null) { return; } if (SpawnManager.Monsters.Contains(instance)) { Trace.LogWarning("Can not add monster instance {0} to table as it already has been added.", instance); return; } // associate monster with area. if (area != null) { CoM.State.SpawnManager.TrackSpawnedMonster(area, instance); } if (location != null) { instance.SpawnLocation = location.Value; instance.X = location.Value.X; instance.Y = location.Value.Y; //todo: floor instance.Floor = location.Value.Floor } SpawnManager.Monsters.Add(instance); }
/** Sets the spawn time for the given area. */ public void SetRespawnTime(MDRArea area, long value) { if (!SpawnInfo.ContainsKey(area)) { SpawnInfo[area] = new SpawnInformation(); } SpawnInfo[area].RespawnTimer = value; }
/** Sets the monster instance to be associdated with the given area. */ public void TrackSpawnedMonster(MDRArea area, MDRMonsterInstance value) { if (!SpawnInfo.ContainsKey(area)) { SpawnInfo[area] = new SpawnInformation(); } SpawnInfo[area].SpawnedMonsters.Add(value); }
/** Returns the respawn time for given area. */ public long GetRespawnTime(MDRArea area) { if (SpawnInfo.ContainsKey(area)) { return(SpawnInfo[area].RespawnTimer); } else { return(0); } }
/** Returns the monster instances associated with given area or null if there are none. */ public List <MDRMonsterInstance> GetSpawnedMonsters(MDRArea area) { if (SpawnInfo.ContainsKey(area)) { var result = SpawnInfo[area].SpawnedMonsters; if (result != null && result.Count == 0) { return(null); } return(result); } else { return(null); } }
/** * Reads the next map from the file. * levelNumberToLoad is the level to load, 1 being the first. */ public MDRMap ReadMap(int levelNumberToLoad) { MDRMap map = new MDRMap(); data.Seek(0, SeekOrigin.Begin); // find how many levels there are int numberOfLevels = data.ReadMDRWord(); if ((levelNumberToLoad <= 0) || (levelNumberToLoad > numberOfLevels)) { data.Close(); throw new Exception("Invalid level number " + levelNumberToLoad); } // get the offset data.RecordSeek(1 + levelNumberToLoad); int levelOffset = data.ReadMDRWord(); // load in the map header data.RecordSeek(levelOffset); int width = data.ReadWord(); int height = data.ReadWord(); int floorNumber = data.ReadWord(); if (floorNumber != levelNumberToLoad) { data.Close(); throw new Exception("Level number in file wrong, expecting " + levelNumberToLoad + " but found " + floorNumber); } NumberOfAreas = data.ReadWord(); NumberOfChutes = data.ReadWord(); NumberOfTeleports = data.ReadWord(); // make sure we got some resonable results if ((width <= 0) || (width > 256) || (height <= 0) || (height > 256)) { data.Close(); throw new Exception("Level dimentions invalid, found " + width + "x" + height + ", maximum size is 256x256"); } if (NumberOfAreas > MDRMap.MAX_AREAS) { data.Close(); throw new Exception("Too many areas in level, found " + NumberOfAreas + " but maximum is " + MDRMap.MAX_AREAS); } if (NumberOfChutes > MDRMap.MAX_CHUTES) { data.Close(); throw new Exception("Too many chutes in level, found " + NumberOfChutes + " but maximum is " + MDRMap.MAX_CHUTES); } if (NumberOfTeleports > MDRMap.MAX_TELEPORTS) { data.Close(); throw new Exception("Too many teleports in level, found " + NumberOfTeleports + " but maximum is " + MDRMap.MAX_TELEPORTS); } // initialize map with a rock frame FieldRecord rockTile = new FieldRecord(0, 0, null); rockTile.Rock = true; map.Initialize(width + 2, height + 2); map.FloorNumber = floorNumber; var AreaLocation = new Vector2[MDRMap.MAX_AREAS]; // load field records data.RecordSeek(levelOffset + 1); for (int ylp = 1; ylp <= height; ylp++) { for (int xlp = 1; xlp <= width; xlp++) { FieldRecord fieldRecord = new FieldRecord(xlp, ylp, map); fieldRecord.AreaNumber = (ushort)data.ReadWord(); //read the field bitvalues as a currency type, and the convert to byte data decimal decValue = data.ReadCurrency(); Int64 value = Convert.ToInt64(decValue); byte[] bitData = BitConverter.GetBytes(value); AreaLocation[fieldRecord.AreaNumber] = new Vector2(xlp, ylp); fieldRecord.BitMask = new BitArray(bitData); // custom adjustment for grass if (fieldRecord.Dirt && fieldRecord.Water) { fieldRecord.Dirt = false; fieldRecord.Water = false; fieldRecord.Grass = true; } // adjust for new wall types if (fieldRecord._alt) { if (fieldRecord.NorthWall.Door) { fieldRecord.NorthWall = new WallRecord(WallType.Arch); } if (fieldRecord.NorthWall.Secret) { fieldRecord.NorthWall = new WallRecord(WallType.Gate); } if (fieldRecord.EastWall.Door) { fieldRecord.EastWall = new WallRecord(WallType.Arch); } if (fieldRecord.EastWall.Secret) { fieldRecord.EastWall = new WallRecord(WallType.Gate); } } // stub: remove traps fieldRecord.Chute = false; fieldRecord.Pit = false; fieldRecord.Teleporter = false; fieldRecord.FaceEast = false; fieldRecord.FaceWest = false; fieldRecord.FaceNorth = false; fieldRecord.FaceSouth = false; map[xlp, ylp] = fieldRecord; map[xlp, ylp].Explored = true; // skip the unused bytes in this 20 byte record data.NextRecord(); } } // rock outline WallRecord wall = new WallRecord(WallType.Wall); for (int lp = 0; lp <= width + 1; lp++) { map[lp, 0].Rock = true; map[lp, 0].NorthWall = wall; map[lp, height + 1].Rock = true; map[lp, height + 1].SouthWall = wall; } for (int lp = 0; lp <= height + 1; lp++) { map[0, lp].Rock = true; map[0, lp].EastWall = wall; map[width + 1, lp].Rock = true; map[width + 1, lp].WestWall = wall; } // Load areas. int localAreaCount = data.ReadMDRWord(); NumberOfAreas = localAreaCount; //if (localAreaCount != NumberOfAreas) // Trace.LogWarning("Area count missmatch expecting " + NumberOfAreas + " but found " + localAreaCount + " assuming " + NumberOfAreas); for (int lp = 0; lp < NumberOfAreas; lp++) { MDRArea area = new MDRArea(); area.Origion = new MDRLocation((int)AreaLocation[lp].x, (int)AreaLocation[lp].y, floorNumber); area.SpawnMask = new MDRSpawnMask(data.ReadUInt32()); int lairID = data.ReadWord(); if (lairID != 0) { area.LairedMonster = CoM.Monsters.ByID(lairID); if (area.LairedMonster == null) { Trace.LogWarning("Import Error [Missing Monster]: Can not find monster of ID:{0} for lair{2} at [{1}].", lairID, area.Origion, lp); } } // some areas will be invalid, so ignore areas with no spawnmask or lair id. if (!(area.SpawnMask.Mask.Count == 0 && lairID == 0)) { map.Area.Add(area); area.Map = map; area.ID = lp; } data.NextRecord(); } data.SkipRecords(200 - NumberOfAreas); data.SkipRecords(1); // no idea why this is necessary, but there is a blank record here before we start with the teleporters // load teleports int localTeleportCount = data.ReadMDRWord(); if (localTeleportCount != NumberOfTeleports) { Trace.LogWarning("Teleport count missmatch expecting " + NumberOfTeleports + " but found " + localTeleportCount + " assuming " + NumberOfTeleports); } for (int lp = 0; lp < NumberOfTeleports; lp++) { TeleportTrapInfo teleport = new TeleportTrapInfo(); teleport.X = data.ReadWord(); teleport.Y = data.ReadWord(); teleport.DestX = data.ReadWord(); teleport.DestY = data.ReadWord(); teleport.DestFloor = data.ReadWord(); data.NextRecord(); if (teleport.IsValid) { map.Teleport.Add(teleport); } } // load chutes int localChuteCount = data.ReadMDRWord(); if (localChuteCount != NumberOfChutes) { Trace.LogWarning("Chute count missmatch expecting " + NumberOfChutes + " but found " + localChuteCount + " assuming " + NumberOfChutes); } for (int lp = 0; lp < NumberOfChutes; lp++) { ChuteTrapInfo chute = new ChuteTrapInfo(); chute.X = data.ReadWord(); chute.Y = data.ReadWord(); chute.DropDepth = data.ReadWord(); data.NextRecord(); if (chute.IsValid) { map.Chute.Add(chute); } } return(map); }