Пример #1
0
        /// <summary>Loads and parses the map.ini from the current map path.</summary>
        private void LoadMapData()
        {
            if (m_filePath == "")
                return;

            if (!File.Exists(m_filePath + Program.MapIniFile))
            {
                Debug.WriteLine("WARNING: map ini does not exist");
                return;
            }

            try
            {
                //Why have the overhead of getprivateprofile when we can just do it ourself?
                m_lastLoad = m_filePath + Program.MapIniFile;
                FileStream stream = File.OpenRead(m_lastLoad);
                StreamReader reader = new StreamReader(stream);
                string line = "";
                string subline = "";
                string[] parts;
                string[] subparts;
                int zoneid;
                int mapid;
                int linenumber = 0;
                int idx = 0;
                FFXIZoneMaps zonemaps = null;
                FFXIImageMap map = null;

                while ((line = reader.ReadLine()) != null)
                {
                    linenumber++;
                    try
                    {
                        if (line.Length == 0 || line[0] == ';' || line[0] == '[') //only care about the data
                            continue;

                        //parse the key/value pair of the ini line
                        parts = line.Split('=');
                        if (parts.Length != 2)
                            continue;

                        //parse the zone/map pair
                        subparts = parts[0].Split('_');
                        if (subparts.Length != 2)
                            continue;

                        zoneid = System.Convert.ToInt16(subparts[0], 16);
                        if (!int.TryParse(subparts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out mapid))
                            continue;

                        //parse the calc and range data
                        subline = parts[1];
                        idx = subline.IndexOf(';');
                        if (idx > -1)
                            subline = subline.Substring(0, idx); //kill comments following the data area
                        subline = subline.Trim();
                        subparts = subline.Split(',');
                        if (subparts.Length == 0 || ((subparts.Length - 4) % 6 != 0)) //ranges are specified in vector pairs
                            continue;

                        //get the zone object
                        if (zonemaps == null || zonemaps.ZoneID != zoneid)
                        {
                            if (!m_zones.ContainsKey(zoneid))
                            {
                                zonemaps = new FFXIZoneMaps(this, zoneid);
                                m_zones.Add(zoneid, zonemaps);
                            }
                            else
                            {
                                zonemaps = m_zones[zoneid];
                            }
                        }

                        if (zonemaps.ContainsKey(mapid)) //only process the same zone/map combo once
                            continue;

                        //create the map object
                        map = new FFXIImageMap(zonemaps, mapid,
                           float.Parse(subparts[0], CultureInfo.InvariantCulture),
                           float.Parse(subparts[1], CultureInfo.InvariantCulture),
                           float.Parse(subparts[2], CultureInfo.InvariantCulture),
                           float.Parse(subparts[3], CultureInfo.InvariantCulture)
                        );

                        //add each range of values
                        int i = 4;
                        while (i < subparts.Length)
                        {
                            map.addRange(
                               float.Parse(subparts[i], CultureInfo.InvariantCulture),      //X1 
                               float.Parse(subparts[i + 2], CultureInfo.InvariantCulture),  //Y1 Y/Z swapped to standard vertex order.
                               float.Parse(subparts[i + 1], CultureInfo.InvariantCulture),  //Z1 Why must we perpetuate bad coordinate ordering?
                               float.Parse(subparts[i + 3], CultureInfo.InvariantCulture),  //X2 
                               float.Parse(subparts[i + 5], CultureInfo.InvariantCulture),  //Y2 Y/Z swapped here too.
                               float.Parse(subparts[i + 4], CultureInfo.InvariantCulture)   //Z2
                            );
                            i += 6;
                        }
                        zonemaps.Add(map);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("error reading line " + linenumber + ": " + ex.Message);
                    }
                }
                reader.Close();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("LoadMapData ERROR: " + ex.Message);
            }
        }
Пример #2
0
 public FFXIImageMapRange(FFXIImageMap map, float x1, float y1, float z1, float x2, float y2, float z2)
 {
     //cache the mins/maxs
     m_map = map;
     SetRange(x1, y1, z1, x2, y2, z2);
 }
Пример #3
0
        public override bool Poll()
        {
            if (Switching)
                return true;
            if (reader == null)
                return false;
            if (reader.HasExited)
                return false;
            if (!Valid)
                throw new InstanceException("FFXI could not be polled becuase the context is invalid.", InstanceExceptionType.InvalidContext);

            try
            {
                //grab the current zone id
                Int32 ZoneID = reader.ReadStruct<Int32>(pZoneID);
                if (ZoneID > 0xFF)
                    ZoneID = ZoneID - 0x1BC;

                //stop all reading while the zone is in flux
                if (ZoneID == 0)
                {
                    lastZone = -1; //make sure the data gets properly reset in case the player zones into the same zone (tractor, warp, etc)
                    lastMapID = -1;
                    return true;
                }

                //If the zone has changed, then clear out any old spawns and load the zone map
                if (ZoneID != lastZone || engine.Data.Empty)
                {
                    //An edit to the map has been made. Inform the user they are about to lose thier changes
                    //  and give them a final opportunity to save them.
                    if (engine.Data.Dirty)
                    {
                        //clone the map data
                        MapData mapcopy = engine.Data.Clone();
                        //pass the closed data to another thread so the current zone can continue processing.
                        DirtyZone(mapcopy);
                    }

                    zoneFinished = false;

                    //get the zone name
                    string shortName = "";
                    if (ZoneID < m_zoneNameShort.Count)
                        shortName = m_zoneNameShort[ZoneID];    //grab the new zone name
                    if (shortName == "")
                        shortName = "Zone" + ZoneID.ToString(); //support unnamed zones, like the mog house

                    //release zone resources consumed by the image map processor
                    if (engine.ShowMapAlternative)
                    {
                        engine.MapAlternativeImage = null;
                        m_imagemaps.ClearCache(lastZone);
                    }

                    //clear the old zone data and load in the new
                    engine.Clear(); //clear both the spawn and map data
                    engine.Data.ZoneName = shortName;
                    engine.Data.LoadZone(shortName); //load the zone map
                    lastZone = ZoneID;
                    lastMapID = -1;
                }

                //read the pointer array in one big lump, and create spawns for any new id's detected
                Int32[] spawnList = reader.ReadStructArray<Int32>(pSpawnStart, listMax); //cant use intptr since its machine dependant
                for (uint i = 0; i < listMax; i++)
                {
                    if (spawnList[i] > 0)
                    {
                        //only add new id's. each spawn is responsible for updating itself.
                        if (!engine.Game.Spawns.ContainsIndex(i))
                        {
                            //create the spawn and add it to the game data
                            FFXISpawn spawn = new FFXISpawn(i, (IntPtr)spawnList[i], this);

                            engine.Game.Spawns.Add(spawn);

                            //spawn.DEBUGHOVER = "pointer: " + spawnList[i].ToString("X") + " index: " + i;

                            //add the spawn to the server lookup table. this is used later to convert the claim id
                            if (spawn.Type == SpawnType.Player)
                            {
                                if (m_ServerIDLookup.ContainsKey(spawn.ServerID))
                                    m_ServerIDLookup[spawn.ServerID] = spawn;
                                else
                                    m_ServerIDLookup.Add(spawn.ServerID, spawn); //add the server id to the lookup table
                            }
                        }
                    }
                }

                //fill in the player and target
                UInt32 myID = reader.ReadStruct<UInt32>(pMyID);
                engine.Game.setPlayer(myID, true);
                UInt32 myTarget = reader.ReadStruct<UInt32>(pMyTarget);
                engine.Game.setTarget(myTarget, true);

                //force each spawn to self update
                engine.Game.Update();

                //determine if the map image alternative requires processing
                if (engine.ShowMapAlternative && (lastPlayerLocation == null || (engine.Game.Player != null && !engine.Game.Player.Location.isEqual(lastPlayerLocation))))
                {
                    //Since the player has moved, determine if the map id has changed
                    lastPlayerLocation = engine.Game.Player.Location.Clone();
                    curMap = m_imagemaps.GetCurrentMap(ZoneID, lastPlayerLocation);

                    //only process if there is a map to display
                    if (curMap != null)
                    {
                        /// IHM EDIT
                        //Send the location in image coordinates to the engine. (I don't like doing it this way.)
                        engine.LocInImage = curMap.Translate(engine.Game.Player.Location);

                        //only process if the map has actually changed
                        if (curMap.MapID != lastMapID)
                        {
                            engine.MapAlternativeImage = curMap.GetImage(); //set the background image
                            RectangleF bounds = curMap.Bounds;                //retrieve the map coodinate boundaries
                            engine.MapAlternativeBounds = bounds;           //set the origin/scale of the background image
                            engine.Data.CheckBounds(bounds);                //expand the map bounds (if necessary) to allow the map to be zoomed all the way out
                            lastMapID = curMap.MapID;                         //set the map id so that the map isnt processed again until a change is made
                            if (MapChanged != null)
                                MapChanged(curMap, new EventArgs());
                        }
                    }
                    else if (engine.MapAlternativeImage != null)
                    {
                        //inform the engine that there is no map to display for the current location
                        engine.MapAlternativeImage = null;
                        lastMapID = -1;
                    }
                }

                if (engine.Game.Spawns.Count > 0 && !zoneFinished)
                {
                    zoneFinished = true;

                    //automatically snap the range into view (if enabled)
                    if (engine.AutoRangeSnap)
                        engine.SnapToRange();
                    if (ZoneChanged != null)
                        ZoneChanged(curMap, new EventArgs());
                }
                return true;
#if DEBUG
         } catch(Exception ex) {
            Debug.WriteLine("Error while polling the process: " + ex.Message);
#else
            }
            catch
            {
#endif
                return false;
            }
        }
Пример #4
0
 /// <summary>Determines if the given map is bound to the zone.</summary>
 public bool ContainsValue(FFXIImageMap map)
 {
     return m_maps.ContainsValue(map);
 }
Пример #5
0
 /// <summary>Creates a new map with the given id, scale, and offset</summary>
 public FFXIImageMap Create(int ID, float scale, float x, float y)
 {
     if (m_maps.ContainsKey(ID))
         return m_maps[ID];
     FFXIImageMap map = new FFXIImageMap(this, ID, scale, x, -scale, y);
     Add(map);
     return map;
 }
Пример #6
0
 public FFXIMapImageEditor() {
    m_hovered = null;
    mapList = new LinkedList<FFXIImageMap>();
 }
Пример #7
0
 /// <summary>Adds the image map to the zone.</summary>
 public void Add(FFXIImageMap map)
 {
     m_maps.Add(map.MapID, map);
 }
Пример #8
0
      private void DrawMap(FFXIImageMap map, Graphics g) {
         if (map == null)
            return;
         RectangleF bounds = map.Bounds;
         Image image = map.GetImage();

         RectangleF dest = RectangleF.FromLTRB(
            window.Engine.CalcClientCoordX(bounds.Left),
            window.Engine.CalcClientCoordY(bounds.Top),
            window.Engine.CalcClientCoordX(bounds.Right),
            window.Engine.CalcClientCoordY(bounds.Bottom)
         );
         if (image != null) {
            g.DrawImage(image, Rectangle.Round(dest), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
         } else {
            g.FillRectangle(bTitleBG, dest);
            g.DrawLine(pHandleBorder, dest.Left, dest.Top, dest.Right, dest.Bottom);
            g.DrawLine(pHandleBorder, dest.Left, dest.Bottom, dest.Right, dest.Top);
         }

         string mapinfo = "Map " + map.MapID + " Scale: " + map.XScale + " Offset: " + map.XOffset + "," + map.YOffset;
         SizeF size = g.MeasureString(mapinfo, SystemFonts.DefaultFont);
         float x = engine.CalcClientCoordX(bounds.X);
         float y = engine.CalcClientCoordY(bounds.Y);
         g.FillRectangle(bTitleBG, x, y, size.Width + 2, size.Height + 2);
         g.DrawString(mapinfo, SystemFonts.DefaultFont, bTitle, x + 1, y + 1);
      }
Пример #9
0
 public void OnMouseLeave(EventArgs e) {
    m_hovered = null;
 }
Пример #10
0
 public void OnMouseMove(MouseEventArgs e) {
    if (panMode) {
       if (editmode == 0 && edittarget == 1) {
          m_selectedMap.SetMapLocation(
             panViewOrigin.X + (float)(((panMouseOrigin.X - e.X) * m_selectedMap.XScale) / engine.Scale),
             panViewOrigin.Y + (float)(((panMouseOrigin.Y - e.Y) * -m_selectedMap.YScale) / engine.Scale)
          );
          engine.UpdateMap();
       } else {
          //default pan mode behavior
          window.Engine.ViewLocation = new PointF(
             (float)(panViewOrigin.X - (float)(panMouseOrigin.X - e.X)),
             (float)(panViewOrigin.Y - (float)(panMouseOrigin.Y - e.Y))
          );
       }
    } else {
       if (editmode == 0) {
          m_hovered = GetMapFromPoint(e.Location);
          if (m_hovered == null || (UserControl.ModifierKeys & Keys.Control) > 0) {
             window.Cursor = Cursors.Default;
          } else {
             window.Cursor = Cursors.SizeAll;
          }
       }
    }
 }
Пример #11
0
      public void OnMouseDown(MouseEventArgs e) {
         if (e.Button == MouseButtons.Left) {
            //if panning the map, then capture the current mouse location as the origin and enable the panning mode
            panViewOrigin = window.Engine.ViewLocation;
            panMouseOrigin = e.Location;
            panMode = true;

            if (editmode == 0) {
               m_selectedMap = GetMapFromPoint(e.Location);
               if (m_selectedMap == null || (UserControl.ModifierKeys & Keys.Control) > 0) {
                  edittarget = 0;
               } else {
                  if (m_selectedMap != mapList.First.Value) {
                     mapList.Remove(m_selectedMap);
                     mapList.AddFirst(m_selectedMap);
                     ui.updateTopMostMap();
                  }
                  panViewOrigin = new PointF(m_selectedMap.XOffset, m_selectedMap.YOffset);
                  edittarget = 1;
               }
            }
         }
      }
Пример #12
0
 public void RemoveMap(FFXIImageMap map) {
    if (imap.CurrentZone.ContainsValue(map)) {
       imap.CurrentZone.Remove(map.MapID);
       mapList.Remove(map);
       ui.updateMapInfo();
    }
 }