示例#1
0
    /**
     * 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);
    }
示例#2
0
 /** 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;
 }
示例#3
0
 /** 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);
 }
示例#4
0
 /** Returns the respawn time for given area. */
 public long GetRespawnTime(MDRArea area)
 {
     if (SpawnInfo.ContainsKey(area))
     {
         return(SpawnInfo[area].RespawnTimer);
     }
     else
     {
         return(0);
     }
 }
示例#5
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);
     }
 }
示例#6
0
        /**
         * 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);
        }