示例#1
0
 public Unit(int xOffset, int yOffset, int zOffset, int id, StaticHouseHelper.TileType flags)
 {
     m_xOffset = xOffset;
     m_yOffset = yOffset;
     m_zOffset = zOffset;
     m_id      = id;
     m_flags   = flags;
 }
示例#2
0
        private static void PickerCallback(Mobile from, Map map, Point3D start, Point3D end, object state)
        {
            object[]  args          = state as object[];
            string    name          = args[0] as string; // house name
            string    description   = args[1] as string; // house description
            bool      items         = false;             // we capture items separatly
            bool      statics       = true;              // we alwaye want statics when capturing a house
            bool      land          = false;             // we never land tiles when capturing a house
            bool      raw           = (bool)args[2];     // raw capture will ignore BaseHouse info
            bool      no_foundation = (bool)args[3];     // remove the foundation
            bool      range         = (bool)args[4];     // specify Z
            bool      patch         = (bool)args[7];     // create a FixerAddon to patch missing tiles (expensive, don't use unless you must)
            BaseHouse houseInRect   = null;              // when not doing raw capture, we extract data directly from the house

            // normalize bounding rect
            if (start.X > end.X)
            {
                int x = start.X;
                start.X = end.X;
                end.X   = x;
            }
            if (start.Y > end.Y)
            {
                int y = start.Y;
                start.Y = end.Y;
                end.Y   = y;
            }

            // if we have a house here and we're not in 'raw capture' mode, extract
            //  the actual multi rect instead of leaving it up to the user ;p
switching_to_Raw_mode:
            if (raw == false)
            {               // check each tile looking for a house
                for (int ix = start.X; ix < end.X; ix++)
                {
                    for (int iy = start.Y; iy < end.Y; iy++)
                    {
                        Point3D point = new Point3D(ix, iy, 16);
                        houseInRect = BaseHouse.FindHouseAt(point, from.Map, 16);
                        if (houseInRect != null)
                        {                           // get the *real* location/dimentions from the multi
                            from.SendMessage(0x40, "Progress: Found a house at this location, extracting info.");
                            MultiComponentList mcl = houseInRect.Components;
                            int x = houseInRect.X + mcl.Min.X;
                            int y = houseInRect.Y + mcl.Min.Y;
                            start.X = x;
                            end.X   = start.X + mcl.Width;
                            start.Y = y;
                            end.Y   = start.Y + mcl.Height;
                            // for houses with plots, use the plot dimentions
                            if (houseInRect is HouseFoundation)
                            {                                   // patch width based on plot size and not multi
                                int MultiID = houseInRect.ItemID;
                                int width = 0; int height = 0;
                                StaticHouseHelper.GetFoundationSize(MultiID, out width, out height);
                                end.X = start.X + width;
                                end.Y = start.Y + height;
                            }
                            goto exit_house_info;
                        }
                    }
                }

                // if we can't find a house here, switch to raw capture mode
                if (houseInRect == null)
                {
                    from.SendMessage(0x40, "Info: No house at this location, switching to Raw mode.");
                    raw = true;
                    goto switching_to_Raw_mode;
                }
            }
            // we're in raw capture mode, help the user by snapping to the next valid plot size
            //	if the rect they selected is not a valid size
            else
            {
                if (!StaticHouseHelper.IsFoundationSizeValid(end.X - start.X, end.Y - start.Y))
                {
                    int tempWidth = end.X - start.X;
                    int tempHeight = end.Y - start.Y;
                    int ix = 0, iy = 0;
                    while (true)
                    {
                        if (StaticHouseHelper.IsFoundationSizeValid(tempWidth + ix, tempHeight))
                        {
                            end.X += ix;
                            from.SendMessage(0x40, String.Format("Info: Snapping to next leagal X plot size."));
                            goto exit_house_info;
                        }
                        else if (StaticHouseHelper.IsFoundationSizeValid(tempWidth, tempHeight + iy))
                        {
                            end.Y += iy;
                            from.SendMessage(0x40, String.Format("Info: Snapping to next leagal Y plot size."));
                            goto exit_house_info;
                        }

                        if (ix == 18 && iy == 18)
                        {
                            break;                                                      // we should exit before hitting this case
                        }
                        if (ix < 18)
                        {
                            ix++;                                                                       // next valid X
                        }
                        if (iy < 18)
                        {
                            iy++;                                                                       // next valid Y
                        }
                    }
                }
            }

            // we now have the 'perfect' rect for BaseHouse being captured.
exit_house_info:

            // do we have a valid plot size?
            if (!StaticHouseHelper.IsFoundationSizeValid(end.X - start.X, end.Y - start.Y))
            {
                from.SendMessage(0x22, "Error: House size " + Convert.ToString(end.X - start.X) + "x" + Convert.ToString(end.Y - start.Y) + " is invalid!");
                from.SendGump(new InternalGump(from, (object[])state));
                return;
            }
            else
            {
                from.SendMessage(0x40, String.Format("Info: Selected plot size {0}x{1}.", end.X - start.X, end.Y - start.Y));
            }

            // calc price based on plot size
            // THIS is the portion an NPC architect will refund... not the tile(plot size) assessment
            //	added below.
            int BasePrice = StaticHouseHelper.GetBasePrice(end.X - start.X, end.Y - start.Y);

            //pla: Check if the house blueprint file already exists, and if not then create one
            if (!Directory.Exists("Data"))
            {
                Directory.CreateDirectory("Data");
            }

            if (!File.Exists(StaticHouseHelper.BlueprintDatabase))
            {
                using (XmlTextWriter writer = new XmlTextWriter(StaticHouseHelper.BlueprintDatabase, System.Text.Encoding.Unicode))
                {
                    writer.WriteStartElement("StaticHousing");
                    writer.WriteEndElement();
                }
            }

            //pla: Create document object for manipulation
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load(StaticHouseHelper.BlueprintDatabase);
            if (xmlDoc == null)
            {
                return;
            }

            // version of this XML format
            //  do not confuse this version with the version of the house.
            XmlNode root                    = xmlDoc.FirstChild;
            double  formatVersion           = 1.0;
            XmlAttributeCollection attrColl = root.Attributes;
            XmlAttribute           attr     = null;

            if (attrColl != null)
            {
                attr = (XmlAttribute)attrColl.GetNamedItem("Version");
            }
            if (attr == null)
            {               // we don't have a version stamp, add one
                XmlNode vattr = xmlDoc.CreateNode(XmlNodeType.Attribute, "Version", "");
                vattr.Value = formatVersion.ToString();
                root.Attributes.SetNamedItem(vattr);
            }

            // a new house
            XmlElement  newHouse = xmlDoc.CreateElement("HouseID");
            Rectangle2D bounds   = new Rectangle2D(start, end);

            // house name
            XmlElement nameElement = xmlDoc.CreateElement("id");

            nameElement.InnerText = name;
            newHouse.AppendChild(nameElement);

            // house description
            //	a deed name is constructed as follows:
            //	"deed to a " + sh.Description
            //	an example name: "deed to a marble house with patio"
            XmlElement descriptionElement = xmlDoc.CreateElement("Description");

            if (description != null && description.Length > 0)
            {
                descriptionElement.InnerText = description;
            }
            else
            {
                descriptionElement.InnerText = "(none)";
            }
            newHouse.AppendChild(descriptionElement);

            // version of the house.
            //  do not confuse with the version of this XML format
            //  this is not the XML format of the house either, it's the construction version
            //	Displayed in the House Gump.
            double     houseVersion        = 1.0;
            XmlElement houseVersionElement = xmlDoc.CreateElement("Version");

            houseVersionElement.InnerText = houseVersion.ToString();
            newHouse.AppendChild(houseVersionElement);

            // Date/Time this version of this house was captured
            //	Displayed in the House Gump.
            DateTime   CaptureDate    = DateTime.Now;
            XmlElement CaptureElement = xmlDoc.CreateElement("Capture");

            CaptureElement.InnerText = CaptureDate.ToString();
            newHouse.AppendChild(CaptureElement);

            // Record region info
            //	we will also capture the (HouseRegion) region info. We don't like the dumb
            //	complete-plot-is-the-region system introduced with Custom Housing, but prefer
            //	the old-school OSI bodle where the region is an array of well defined rects.
            //	we use the rect editing tools on copy1 of the Custom House, then recapture to
            //	record the region info
            if (raw == false && houseInRect != null)
            {
                Region r = houseInRect.Region;
                if (!(r == null || r.Coords == null || r.Coords.Count == 0))
                {
                    ArrayList c = r.Coords;

                    XmlElement regionElement = xmlDoc.CreateElement("Region");
                    XmlElement rectElement   = null;
                    for (int i = 0; i < c.Count; i++)
                    {
                        if (c[i] is Rectangle2D)
                        {
                            int width  = ((Rectangle2D)(c[i])).Width;
                            int height = ((Rectangle2D)(c[i])).Height;
                            int x      = ((Rectangle2D)(c[i])).Start.X - start.X;
                            int y      = ((Rectangle2D)(c[i])).Start.Y - start.Y;
                            if (x < 0)
                            {
                                x = 0;
                            }
                            if (y < 0)
                            {
                                y = 0;
                            }

                            XmlElement CoordsElement = xmlDoc.CreateElement("Rectangle2D");

                            rectElement           = xmlDoc.CreateElement("x");
                            rectElement.InnerText = x.ToString();
                            CoordsElement.AppendChild(rectElement);

                            rectElement           = xmlDoc.CreateElement("y");
                            rectElement.InnerText = y.ToString();
                            CoordsElement.AppendChild(rectElement);

                            rectElement           = xmlDoc.CreateElement("width");
                            rectElement.InnerText = width.ToString();
                            CoordsElement.AppendChild(rectElement);

                            rectElement           = xmlDoc.CreateElement("height");
                            rectElement.InnerText = height.ToString();
                            CoordsElement.AppendChild(rectElement);

                            regionElement.AppendChild(CoordsElement);
                        }
                    }

                    newHouse.AppendChild(regionElement);
                }
            }

            sbyte min = sbyte.MinValue;
            sbyte max = sbyte.MaxValue;

            try { min = sbyte.Parse(args[5] as string); }
            catch (Exception ex) { EventSink.InvokeLogException(new LogExceptionEventArgs(ex)); }
            try { max = sbyte.Parse(args[6] as string); }
            catch (Exception ex) { EventSink.InvokeLogException(new LogExceptionEventArgs(ex)); }

            if (max < min)
            {
                sbyte temp = max;
                max = min;
                min = temp;
            }

            Hashtable tiles = new Hashtable();

            // (x == end.X || y == end.Y) will be steps or other deco outside the plot
            // see below where we output statics and set TileType 'flags'
            if (statics)
            {
                for (int x = start.X; x <= end.X; x++)
                {
                    for (int y = start.Y; y <= end.Y; y++)
                    {
                        ArrayList list = map.GetTilesAt(new Point2D(x, y), items, land, statics);

                        if (range)
                        {
                            ArrayList remove = new ArrayList();

                            foreach (Tile t in list)
                            {
                                if (t.Z < min || t.Z > max)
                                {
                                    remove.Add(t);
                                }
                            }

                            foreach (Tile t in remove)
                            {
                                list.Remove(t);
                            }
                        }

                        if (list != null && list.Count > 0)
                        {
                            tiles[new Point2D(x, y)] = list;
                        }
                    }
                }
            }

            // we increase the bounds by one here to match the way we scan for static above, that is: including end.X and end.Y
            //	the end.X and end.Y allows us to pick up things on the steps, and the house sign hanger
            Rectangle2D       iBounds = new Rectangle2D(bounds.X, bounds.Y, bounds.Width + 1, bounds.Height + 1);
            IPooledEnumerable en      = map.GetItemsInBounds(iBounds);
            ArrayList         target  = new ArrayList();
            bool foundSign            = false;

            // info pulled from captured house
            DateTime BuiltOn              = DateTime.MaxValue;
            string   OriginalOwnerName    = "(unknown)";
            string   OriginalOwnerAccount = "(unknown)";
            Serial   OriginalOwnerSerial  = Serial.MinusOne;
            Point3D  SignLocation         = Point3D.Zero;       // not used
            int      SignHangerGraphic    = 0xB98;              // default
            int      SignpostGraphic      = 0x09;               // default

            try
            {
                // (x == end.X || y == end.Y) will be steps or other deco outside the plot
                // see below where we output statics and set TileType 'flags'
                foreach (object o in en)
                {
                    // remove all doors
                    if (o is BaseDoor)
                    {
                        from.SendMessage(0x40, "Progress: removing door.");
                        continue;
                    }

                    // Remove SignHanger from the outside of a Custom House
                    //	we look for it at a particular location
                    if (raw == false && houseInRect != null && houseInRect is HouseFoundation == true)
                    {
                        if (IsSignHanger(o) && (o as Item).Y == bounds.Y + bounds.Height)
                        {
                            from.SendMessage(0x40, "Progress: removing sign hanger.");
                            SignHangerGraphic = (o as Item).ItemID;
                            continue;
                        }
                    }

                    // Remove Signpost  from the outside of a Custom House
                    //	we look for it at a particular location
                    if (raw == false && houseInRect != null && houseInRect is HouseFoundation == true)
                    {
                        if (IsSignpost(o) && (o as Item).Y == bounds.Y + bounds.Height - 1)
                        {
                            from.SendMessage(0x40, "Progress: removing Signpost.");
                            SignpostGraphic = (o as Item).ItemID;
                            continue;
                        }
                    }

                    // any BaseHouse
                    if (o is HouseSign)
                    {                       // suck the meaningful info from the house sign
                        from.SendMessage(0x40, "Progress: Processing house sign.");
                        HouseSign sign  = o as HouseSign;
                        BaseHouse house = sign.Structure;
                        if (house != null)
                        {                           // from house
                            BuiltOn = house.BuiltOn;
                        }
                        // from sign
                        OriginalOwnerName    = sign.Owner.Name;
                        OriginalOwnerAccount = sign.Owner.Account.ToString();
                        OriginalOwnerSerial  = sign.Owner.Serial;
                        SignLocation         = sign.Location;
                        foundSign            = true;
                        continue;
                    }

                    // GM built or OSI town static structure
                    if (o is StaticHouseSign)
                    {                       // suck the meaningful info from the house sign
                        from.SendMessage(0x40, "Progress: Processing static house sign.");
                        StaticHouseSign sign = o as StaticHouseSign;
                        // from sign
                        BuiltOn              = sign.BuiltOn;
                        OriginalOwnerName    = sign.Owner.Name;
                        OriginalOwnerAccount = sign.Owner.Account.ToString();
                        OriginalOwnerSerial  = sign.Owner.Serial;
                        SignLocation         = sign.Location;
                        foundSign            = true;
                        continue;
                    }

                    // outside the rect?
                    if (range && ((o as Static).Z < min || (o as Static).Z > max))
                    {
                        continue;
                    }

                    target.Add(o);
                }

                // on OSI houses the sign falls outside the multi-rect
                if (raw == false && houseInRect != null && foundSign == false)
                {
                    // suck the meaningful info from the house sign
                    from.SendMessage(0x40, "Progress: Processing house sign.");
                    HouseSign sign  = houseInRect.Sign;
                    BaseHouse house = sign.Structure;
                    if (house != null)
                    {                       // from house
                        BuiltOn = house.BuiltOn;
                    }
                    // from sign
                    OriginalOwnerName    = sign.Owner.Name;
                    OriginalOwnerAccount = sign.Owner.Account.ToString();
                    OriginalOwnerSerial  = sign.Owner.Serial;
                    SignLocation         = sign.Location;
                    foundSign            = true;
                }
            }
            catch (Exception er)
            {
                LogHelper.LogException(er);
                Console.WriteLine(er.ToString());
                from.SendMessage(0x40, "Info: The targeted items have been modified. Please retry.");
                return;
            }
            finally
            {
                en.Free();
            }

            // captured houses need a sign. for static houses, [add StaticHouseSign and set props
            // we also use the location if the sign as the location for the real sign during construction
            if (foundSign == false)
            {
                from.SendMessage(0x22, "Warning: No StaticHouseSign found for static house.");
                from.SendMessage(0x22, "Warning: [add StaticHouseSign and set props.");
                // don't fail.. assume the XML will be hand edited
            }

            if (target.Count == 0 && tiles.Keys.Count == 0)
            {
                from.SendMessage(0x22, "Error: No items have been selected.");
                return;
            }

            /* -- save the house builder / designed info --
             * BuiltOn = sign.BuiltOn;
             * OriginalOwnerName = sign.OriginalOwner.Name;
             * OriginalOwnerAccount = sign.OriginalOwner.Account.ToString();
             * OriginalOwnerSerial = sign.OriginalOwner.Serial;
             * SignLocation = sign.Location;
             */

            // Date/Time this version of this house was created
            //	Displayed in the House Gump as the revision date
            XmlElement BuiltOnElement = xmlDoc.CreateElement("BuiltOn");

            CaptureElement.InnerText = BuiltOn.ToString();
            newHouse.AppendChild(CaptureElement);

            // OriginalOwnerName
            //	Displayed in the House Gump.
            XmlElement OriginalOwnerNameElement = xmlDoc.CreateElement("OriginalOwnerName");

            OriginalOwnerNameElement.InnerText = OriginalOwnerName.ToString();
            newHouse.AppendChild(OriginalOwnerNameElement);

            // OriginalOwnerAccount
            XmlElement OriginalOwnerAccountElement = xmlDoc.CreateElement("OriginalOwnerAccount");

            OriginalOwnerAccountElement.InnerText = OriginalOwnerAccount.ToString();
            newHouse.AppendChild(OriginalOwnerAccountElement);

            // OriginalOwnerSerial
            //	Displayed in the House Gump as the 'designer's licence number'
            XmlElement OriginalOwnerSerialElement = xmlDoc.CreateElement("OriginalOwnerSerial");

            OriginalOwnerSerialElement.InnerText = OriginalOwnerSerial.ToString();
            newHouse.AppendChild(OriginalOwnerSerialElement);

            // SignLocation
            //	not used
            XmlElement SignLocationElement = xmlDoc.CreateElement("SignLocation");

            SignLocationElement.InnerText = "(unused)" + SignLocation.ToString();
            newHouse.AppendChild(SignLocationElement);

            // SignHangerGraphic
            XmlElement SignHangerGraphicElement = xmlDoc.CreateElement("SignHangerGraphic");

            SignHangerGraphicElement.InnerText = SignHangerGraphic.ToString();
            newHouse.AppendChild(SignHangerGraphicElement);

            // SignpostGraphic
            XmlElement SignpostGraphicElement = xmlDoc.CreateElement("SignpostGraphic");

            SignpostGraphicElement.InnerText = SignpostGraphic.ToString();
            newHouse.AppendChild(SignpostGraphicElement);

            // Get center
            Point3D center = new Point3D();

            center.Z = 127;

            int x1 = bounds.End.X;
            int y1 = bounds.End.Y;
            int x2 = bounds.Start.X;
            int y2 = bounds.Start.Y;

            // Get correct bounds
            foreach (object o in target)
            {
                Item item = o as Item;
                if (item == null)
                {
                    continue;
                }

                // don't factor these tiles as they are outside the bounding rect.
                //	(steps most likely)
                if (item.X >= end.X || item.Y >= end.Y)
                {
                    continue;
                }

                if (item.Z < center.Z)
                {
                    center.Z = item.Z;
                }

                x1 = Math.Min(x1, item.X);
                y1 = Math.Min(y1, item.Y);
                x2 = Math.Max(x2, item.X);
                y2 = Math.Max(y2, item.Y);
            }

            // Get correct bounds
            foreach (Point2D p in tiles.Keys)
            {
                ArrayList list = tiles[p] as ArrayList;

                // don't factor these tiles as they are outside the bounding rect.
                //	(steps most likely)
                if (p.X >= end.X || p.Y >= end.Y)
                {
                    continue;
                }

                foreach (Tile t in list)
                {
                    if (t.Z < center.Z)
                    {
                        center.Z = t.Z;
                    }
                }

                x1 = Math.Min(x1, p.X);
                y1 = Math.Min(y1, p.Y);
                x2 = Math.Max(x2, p.X);
                y2 = Math.Max(y2, p.Y);
            }

            center.X = x1 + ((x2 - x1) / 2);
            center.Y = y1 + ((y2 - y1) / 2);

            // width
            int        PlotWidth    = end.X - start.X;
            XmlElement widthElement = xmlDoc.CreateElement("Width");

            widthElement.InnerText = PlotWidth.ToString();
            newHouse.AppendChild(widthElement);

            // height
            int        PlotHeight    = end.Y - start.Y;
            XmlElement heightElement = xmlDoc.CreateElement("Height");

            heightElement.InnerText = PlotHeight.ToString();
            newHouse.AppendChild(heightElement);

            XmlElement multiElement = xmlDoc.CreateElement("Multi");
            XmlElement tempElement  = null;
            ArrayList  tileTable    = new ArrayList();

            // Statics - add to master list
            foreach (Point2D p in tiles.Keys)
            {
                ArrayList list = tiles[p] as ArrayList;

                int xOffset = p.X - center.X;
                int yOffset = p.Y - center.Y;
                StaticHouseHelper.TileType flags = StaticHouseHelper.TileType.Normal;

                // mark these tiles as existing outside the bounding rect (steps most likely)
                if (p.X >= end.X || p.Y >= end.Y)
                {
                    flags |= StaticHouseHelper.TileType.OutsideRect;
                }

                foreach (Tile t in list)
                {
                    int zOffset = t.Z - center.Z;
                    int id      = t.ID & 0x3FFF;

                    Unit unit = new Unit(xOffset, yOffset, zOffset, id, flags);
                    bool add  = true;

                    foreach (Unit existing in tileTable)
                    {
                        if (existing.m_xOffset == unit.m_xOffset &&
                            existing.m_yOffset == unit.m_yOffset &&
                            existing.m_zOffset == unit.m_zOffset)
                        {
                            if (existing.m_id == unit.m_id)
                            {
                                add = false;
                                break;
                            }
                            else
                            {
                                if (patch == true)
                                {
                                    unit.m_flags |= StaticHouseHelper.TileType.Overlapped;
                                }
                            }
                        }
                    }

                    // only add if unique
                    if (add == true)
                    {
                        tileTable.Add(unit);
                    }
                    else
                    {
                        from.SendMessage(0x40, "Progress: Ignoring duplicate tile.");
                    }
                }
            }

            // Items - add to master list
            foreach (Object o in target)
            {
                Item item = o as Item;
                if (item == null)
                {
                    continue;
                }

                int xOffset = item.X - center.X;
                int yOffset = item.Y - center.Y;
                int zOffset = item.Z - center.Z;
                int id      = item.ItemID;
                StaticHouseHelper.TileType flags = StaticHouseHelper.TileType.Normal;

                // aftermarket addons are 'patched' later
                if (item is AddonComponent || item is StaticHouseHelper.FixerAddon)
                {
                    flags |= StaticHouseHelper.TileType.Patch;
                }

                // mark these tiles as existing outside the bounding rect (steps most likely)
                if (item.X >= end.X || item.Y >= end.Y)
                {
                    flags |= StaticHouseHelper.TileType.OutsideRect;
                }

                Unit unit = new Unit(xOffset, yOffset, zOffset, id, flags);
                bool add  = true;

                foreach (Unit existing in tileTable)
                {
                    if (existing.m_xOffset == unit.m_xOffset &&
                        existing.m_yOffset == unit.m_yOffset &&
                        existing.m_zOffset == unit.m_zOffset)
                    {
                        if (existing.m_id == unit.m_id)
                        {
                            if ((unit.m_flags & StaticHouseHelper.TileType.Patch) != 0)                                         // if the one we are trying the add is a patch..
                            {
                                existing.m_flags |= StaticHouseHelper.TileType.Patch;                                           // convert the existing one to the patch and don't add this one
                            }
                            add = false;
                            break;
                        }
                        else
                        {
                            if (patch == true)
                            {
                                unit.m_flags |= StaticHouseHelper.TileType.Overlapped;
                            }
                        }
                    }
                }

                // only add if unique
                if (add == true)
                {
                    tileTable.Add(unit);
                }
                else
                {
                    from.SendMessage(0x40, "Progress: Ignoring duplicate tile.");
                }
            }

            // Preprocess the list - pass I
            ArrayList removeList = new ArrayList();

            foreach (Unit unit in tileTable)
            {
                Item o = new Item(unit.m_id);

                // remove the foundation and fixup the
                if (no_foundation == true)
                {
                    if (unit.m_zOffset == 0)
                    {
                        // remove foundation tiles
                        if (unit.m_xOffset == start.X - center.X ||
                            unit.m_yOffset == start.Y - center.Y ||
                            unit.m_xOffset == (end.X - center.X) - 1 ||
                            unit.m_yOffset == (end.Y - center.Y) - 1)
                        {
                            removeList.Add(unit);
                        }

                        // steps
                        if ((unit.m_flags & StaticHouseHelper.TileType.OutsideRect) != 0)
                        {
                            removeList.Add(unit);
                        }
                    }
                    // dirt tiles
                    else if (unit.m_zOffset == 7 && unit.m_id == 12788)
                    {
                        removeList.Add(unit);
                    }
                    else
                    {
                        // move all tiles down 7
                        //	bug: when we move down 7, tiles at 0 get clipped.
                        unit.m_zOffset -= 7;
                    }
                }

                // Remove SignHanger on outside of an OSI house
                if (raw == false && houseInRect != null && houseInRect is HouseFoundation == false)
                {
                    if (IsSignHanger(o) && unit.m_yOffset * 2 == PlotHeight)
                    {
                        from.SendMessage(0x40, "Progress: removing sign hanger.");
                        removeList.Add(unit);
                    }
                }

                // remove all doors
                if (o is BaseDoor)
                {
                    from.SendMessage(0x40, "Progress: removing door.");
                    removeList.Add(unit);
                }
            }

            // preprocess - pass II
            //	remove / process all things found in pass I
            foreach (Unit unit in removeList)
            {
                if (tileTable.Contains(unit))
                {
                    tileTable.Remove(unit);
                }
            }

            // house price
            //	price is a base price based on the plot size + a per tile cost (PTC).
            //	PTC is greater as the plot gets bigger .. this will encourage smaller houses, and 'tax' the big land hogs.
            //	the numbers were heuristically derived by looking at a very large and complex 18x18 and deciding that we wanted to add
            //	about 1,000,000 to the price, then dividing that by the number of tiles on this house (1130) and came up with a cost of approx
            //	885 per tile. We then use the logic 18x18 = 36 and 885/32 == 24 which gives us the base PTC. We then multiply
            //	24 * (width + height) to get the actual PTC for this house.
            //	so using this system above, a small 8x8 house has a PTC of 384 where a large 18x18 has a pertile cost of 864
            int        price        = BasePrice + (tileTable.Count * (24 * (PlotWidth + PlotWidth)));
            XmlElement priceElement = xmlDoc.CreateElement("Price");

            priceElement.InnerText = BasePrice.ToString();
            newHouse.AppendChild(priceElement);

            // Okay, write out all tile data
            foreach (Unit unit in tileTable)
            {
                XmlElement singleMultiElement = xmlDoc.CreateElement("Graphic");

                tempElement           = xmlDoc.CreateElement("id");
                tempElement.InnerText = unit.m_id.ToString();
                singleMultiElement.AppendChild(tempElement);

                tempElement           = xmlDoc.CreateElement("x");
                tempElement.InnerText = unit.m_xOffset.ToString();
                singleMultiElement.AppendChild(tempElement);

                tempElement           = xmlDoc.CreateElement("y");
                tempElement.InnerText = unit.m_yOffset.ToString();
                singleMultiElement.AppendChild(tempElement);

                tempElement           = xmlDoc.CreateElement("z");
                tempElement.InnerText = unit.m_zOffset.ToString();
                singleMultiElement.AppendChild(tempElement);

                tempElement           = xmlDoc.CreateElement("flags");
                tempElement.InnerText = ((int)unit.m_flags).ToString();
                singleMultiElement.AppendChild(tempElement);

                multiElement.AppendChild(singleMultiElement);
            }

            // stats

            /*int total = tileTable.Count, deco = 0, patch = 0;
             * foreach (Unit existing in tileTable)
             * {
             *      //StaticHouseHelper.TileType flags = StaticHouseHelper.TileType.Normal;
             *      //StaticHouseHelper.TileType.OutsideRect;
             *      //StaticHouseHelper.TileType.Overlapped;
             *      if (existing.m_flags & StaticHouseHelper.TileType.OutsideRect != 0)
             *              deco++;
             *
             *      if (existing.m_flags & StaticHouseHelper.TileType.Overlapped != 0)
             *              patch++;
             * }
             * from.SendMessage(String.Format("{0} total tiles of which {1} were outside the foundation and {2} were patch tiles.",total, deco, patch));*/

            newHouse.AppendChild(multiElement);
            xmlDoc["StaticHousing"].AppendChild(newHouse);
            xmlDoc.Save(StaticHouseHelper.BlueprintDatabase);
            from.SendMessage("Blueprint creation successful");

            // give the GM a deed to test with
            from.SendMessage("A deed has been placed in your backpack");
            from.AddToBackpack(new StaticDeed(name, description));
        }
示例#3
0
			public Unit(int xOffset, int yOffset, int zOffset, int id, StaticHouseHelper.TileType flags)
			{
				m_xOffset = xOffset;
				m_yOffset = yOffset;
				m_zOffset = zOffset;
				m_id = id;
				m_flags = flags;
			}