From 41b9baa054b135479939528016e31cbad4a9d765 Mon Sep 17 00:00:00 2001 From: mingchen Date: Mon, 16 Jul 2007 19:52:46 +0000 Subject: *Adding some more files --- OpenSim/Region/Environment/LandManagement/Land.cs | 599 ++++++++++++++++++++++ 1 file changed, 599 insertions(+) create mode 100644 OpenSim/Region/Environment/LandManagement/Land.cs (limited to 'OpenSim/Region/Environment/LandManagement/Land.cs') diff --git a/OpenSim/Region/Environment/LandManagement/Land.cs b/OpenSim/Region/Environment/LandManagement/Land.cs new file mode 100644 index 0000000..b333f36 --- /dev/null +++ b/OpenSim/Region/Environment/LandManagement/Land.cs @@ -0,0 +1,599 @@ +using System; +using System.Collections.Generic; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Environment.LandManagement +{ + #region Parcel Class + /// + /// Keeps track of a specific piece of land's information + /// + public class Land + { + #region Member Variables + public LandData landData = new LandData(); + public List primsOverMe = new List(); + + public Scene m_world; + + private bool[,] landBitmap = new bool[64, 64]; + + #endregion + + + #region Constructors + public Land(LLUUID owner_id, bool is_group_owned, Scene world) + { + m_world = world; + landData.ownerID = owner_id; + landData.isGroupOwned = is_group_owned; + + } + #endregion + + + #region Member Functions + + #region General Functions + /// + /// Checks to see if this land object contains a point + /// + /// + /// + /// Returns true if the piece of land contains the specified point + public bool containsPoint(int x, int y) + { + if (x >= 0 && y >= 0 && x <= 256 && x <= 256) + { + return (landBitmap[x / 4, y / 4] == true); + } + else + { + return false; + } + } + + public Land Copy() + { + Land newLand = new Land(this.landData.ownerID, this.landData.isGroupOwned, m_world); + + //Place all new variables here! + newLand.landBitmap = (bool[,])(this.landBitmap.Clone()); + newLand.landData = landData.Copy(); + + return newLand; + } + + #endregion + + + #region Packet Request Handling + /// + /// Sends land properties as requested + /// + /// ID sent by client for them to keep track of + /// Bool sent by client for them to use + /// Object representing the client + public void sendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) + { + + ParcelPropertiesPacket updatePacket = new ParcelPropertiesPacket(); + updatePacket.ParcelData.AABBMax = landData.AABBMax; + updatePacket.ParcelData.AABBMin = landData.AABBMin; + updatePacket.ParcelData.Area = landData.area; + updatePacket.ParcelData.AuctionID = landData.auctionID; + updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented + + updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray; + + updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc); + updatePacket.ParcelData.Category = (byte)landData.category; + updatePacket.ParcelData.ClaimDate = landData.claimDate; + updatePacket.ParcelData.ClaimPrice = landData.claimPrice; + updatePacket.ParcelData.GroupID = landData.groupID; + updatePacket.ParcelData.GroupPrims = landData.groupPrims; + updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned; + updatePacket.ParcelData.LandingType = (byte)landData.landingType; + updatePacket.ParcelData.LocalID = landData.localID; + if (landData.area > 0) + { + updatePacket.ParcelData.MaxPrims = Convert.ToInt32(Math.Round((Convert.ToDecimal(landData.area) / Convert.ToDecimal(65536)) * 15000 * Convert.ToDecimal(m_world.RegionInfo.estateSettings.objectBonusFactor))); + } + else + { + updatePacket.ParcelData.MaxPrims = 0; + } + updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale; + updatePacket.ParcelData.MediaID = landData.mediaID; + updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL); + updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL); + updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName); + updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented + updatePacket.ParcelData.OtherCount = 0; //unemplemented + updatePacket.ParcelData.OtherPrims = landData.otherPrims; + updatePacket.ParcelData.OwnerID = landData.ownerID; + updatePacket.ParcelData.OwnerPrims = landData.ownerPrims; + updatePacket.ParcelData.ParcelFlags = landData.landFlags; + updatePacket.ParcelData.ParcelPrimBonus = m_world.RegionInfo.estateSettings.objectBonusFactor; + updatePacket.ParcelData.PassHours = landData.passHours; + updatePacket.ParcelData.PassPrice = landData.passPrice; + updatePacket.ParcelData.PublicCount = 0; //unemplemented + updatePacket.ParcelData.RegionDenyAnonymous = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.DenyAnonymous) > 0); + updatePacket.ParcelData.RegionDenyIdentified = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.DenyIdentified) > 0); + updatePacket.ParcelData.RegionDenyTransacted = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.DenyTransacted) > 0); + updatePacket.ParcelData.RegionPushOverride = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.RestrictPushObject) > 0); + updatePacket.ParcelData.RentPrice = 0; + updatePacket.ParcelData.RequestResult = request_result; + updatePacket.ParcelData.SalePrice = landData.salePrice; + updatePacket.ParcelData.SelectedPrims = landData.selectedPrims; + updatePacket.ParcelData.SelfCount = 0;//unemplemented + updatePacket.ParcelData.SequenceID = sequence_id; + if (landData.simwideArea > 0) + { + updatePacket.ParcelData.SimWideMaxPrims = Convert.ToInt32(Math.Round((Convert.ToDecimal(landData.simwideArea) / Convert.ToDecimal(65536)) * 15000 * Convert.ToDecimal(m_world.RegionInfo.estateSettings.objectBonusFactor))); + } + else + { + updatePacket.ParcelData.SimWideMaxPrims = 0; + } + updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims; + updatePacket.ParcelData.SnapSelection = snap_selection; + updatePacket.ParcelData.SnapshotID = landData.snapshotID; + updatePacket.ParcelData.Status = (byte)landData.landStatus; + updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims + landData.selectedPrims; + updatePacket.ParcelData.UserLocation = landData.userLocation; + updatePacket.ParcelData.UserLookAt = landData.userLookAt; + remote_client.OutPacket((Packet)updatePacket); + } + + public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) + { + if (remote_client.AgentId == landData.ownerID) + { + //Needs later group support + landData.authBuyerID = packet.ParcelData.AuthBuyerID; + landData.category = (libsecondlife.Parcel.ParcelCategory)packet.ParcelData.Category; + landData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc); + landData.groupID = packet.ParcelData.GroupID; + landData.landingType = packet.ParcelData.LandingType; + landData.mediaAutoScale = packet.ParcelData.MediaAutoScale; + landData.mediaID = packet.ParcelData.MediaID; + landData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL); + landData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL); + landData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name); + landData.landFlags = packet.ParcelData.ParcelFlags; + landData.passHours = packet.ParcelData.PassHours; + landData.passPrice = packet.ParcelData.PassPrice; + landData.salePrice = packet.ParcelData.SalePrice; + landData.snapshotID = packet.ParcelData.SnapshotID; + landData.userLocation = packet.ParcelData.UserLocation; + landData.userLookAt = packet.ParcelData.UserLookAt; + sendLandUpdateToAvatarsOverMe(); + + + } + } + + public void sendLandUpdateToAvatarsOverMe() + { + List avatars = m_world.RequestAvatarList(); + for (int i = 0; i < avatars.Count; i++) + { + Land over = m_world.LandManager.getLandObject((int)Math.Round(avatars[i].Pos.X), (int)Math.Round(avatars[i].Pos.Y)); + if (over.landData.localID == this.landData.localID) + { + sendLandProperties(0, false, 0, avatars[i].ControllingClient); + } + } + } + #endregion + + + #region Update Functions + /// + /// Updates the AABBMin and AABBMax values after area/shape modification of the land object + /// + private void updateAABBAndAreaValues() + { + int min_x = 64; + int min_y = 64; + int max_x = 0; + int max_y = 0; + int tempArea = 0; + int x, y; + for (x = 0; x < 64; x++) + { + for (y = 0; y < 64; y++) + { + if (landBitmap[x, y] == true) + { + if (min_x > x) min_x = x; + if (min_y > y) min_y = y; + if (max_x < x) max_x = x; + if (max_y < y) max_y = y; + tempArea += 16; //16sqm peice of land + } + } + } + landData.AABBMin = new LLVector3((float)(min_x * 4), (float)(min_y * 4), (float)m_world.Terrain.get((min_x * 4), (min_y * 4))); + landData.AABBMax = new LLVector3((float)(max_x * 4), (float)(max_y * 4), (float)m_world.Terrain.get((max_x * 4), (max_y * 4))); + landData.area = tempArea; + } + + public void updateLandBitmapByteArray() + { + landData.landBitmapByteArray = convertLandBitmapToBytes(); + } + + /// + /// Update all settings in land such as area, bitmap byte array, etc + /// + public void forceUpdateLandInfo() + { + this.updateAABBAndAreaValues(); + this.updateLandBitmapByteArray(); + } + + public void setLandBitmapFromByteArray() + { + landBitmap = convertBytesToLandBitmap(); + } + #endregion + + + #region Land Bitmap Functions + /// + /// Sets the land's bitmap manually + /// + /// 64x64 block representing where this land is on a map + public void setLandBitmap(bool[,] bitmap) + { + if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap"); + } + else + { + //Valid: Lets set it + landBitmap = bitmap; + forceUpdateLandInfo(); + + } + } + /// + /// Gets the land's bitmap manually + /// + /// + public bool[,] getLandBitmap() + { + return landBitmap; + } + /// + /// Converts the land bitmap to a packet friendly byte array + /// + /// + private byte[] convertLandBitmapToBytes() + { + byte[] tempConvertArr = new byte[512]; + byte tempByte = 0; + int x, y, i, byteNum = 0; + i = 0; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++ % 8)); + if (i % 8 == 0) + { + tempConvertArr[byteNum] = tempByte; + tempByte = (byte)0; + i = 0; + byteNum++; + } + } + } + return tempConvertArr; + } + + private bool[,] convertBytesToLandBitmap() + { + bool[,] tempConvertMap = new bool[64, 64]; + tempConvertMap.Initialize(); + byte tempByte = 0; + int x = 0, y = 0, i = 0, bitNum = 0; + for (i = 0; i < 512; i++) + { + tempByte = landData.landBitmapByteArray[i]; + for (bitNum = 0; bitNum < 8; bitNum++) + { + bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte)1); + tempConvertMap[x, y] = bit; + x++; + if (x > 63) + { + x = 0; + y++; + } + + } + + } + return tempConvertMap; + } + /// + /// Full sim land object creation + /// + /// + public static bool[,] basicFullRegionLandBitmap() + { + return getSquareLandBitmap(0, 0, 256, 256); + } + + /// + /// Used to modify the bitmap between the x and y points. Points use 64 scale + /// + /// + /// + /// + /// + /// + public static bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) + { + + bool[,] tempBitmap = new bool[64, 64]; + tempBitmap.Initialize(); + + tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); + return tempBitmap; + } + + /// + /// Change a land bitmap at within a square and set those points to a specific value + /// + /// + /// + /// + /// + /// + /// + /// + public static bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value) + { + if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); + } + + int x, y; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + if (x >= start_x / 4 && x < end_x / 4 + && y >= start_y / 4 && y < end_y / 4) + { + land_bitmap[x, y] = set_value; + } + } + } + return land_bitmap; + } + /// + /// Join the true values of 2 bitmaps together + /// + /// + /// + /// + public static bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) + { + if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); + } + if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); + + } + + int x, y; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + if (bitmap_add[x, y]) + { + bitmap_base[x, y] = true; + } + } + } + return bitmap_base; + } + #endregion + + #region Object Select and Object Owner Listing + public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client) + { + List resultLocalIDs = new List(); + foreach (SceneObject obj in primsOverMe) + { + if (obj.rootLocalID > 0) + { + if (request_type == LandManager.LAND_SELECT_OBJECTS_OWNER && obj.rootPrimitive.OwnerID == this.landData.ownerID) + { + resultLocalIDs.Add(obj.rootLocalID); + } + else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && false) //TODO: change false to group support! + { + + } + else if (request_type == LandManager.LAND_SELECT_OBJECTS_OTHER && obj.rootPrimitive.OwnerID != remote_client.AgentId) + { + resultLocalIDs.Add(obj.rootLocalID); + } + } + } + + + bool firstCall = true; + int MAX_OBJECTS_PER_PACKET = 251; + ForceObjectSelectPacket pack = new ForceObjectSelectPacket(); + ForceObjectSelectPacket.DataBlock[] data; + while (resultLocalIDs.Count > 0) + { + if (firstCall) + { + pack._Header.ResetList = true; + firstCall = false; + } + else + { + pack._Header.ResetList = false; + } + + if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET) + { + data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET]; + } + else + { + data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count]; + } + + int i; + for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++) + { + data[i] = new ForceObjectSelectPacket.DataBlock(); + data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]); + resultLocalIDs.RemoveAt(0); + } + pack.Data = data; + remote_client.OutPacket((Packet)pack); + } + + } + public void sendLandObjectOwners(IClientAPI remote_client) + { + Dictionary ownersAndCount = new Dictionary(); + foreach (SceneObject obj in primsOverMe) + { + if (!ownersAndCount.ContainsKey(obj.rootPrimitive.OwnerID)) + { + ownersAndCount.Add(obj.rootPrimitive.OwnerID, 0); + } + ownersAndCount[obj.rootPrimitive.OwnerID] += obj.primCount; + } + if (ownersAndCount.Count > 0) + { + + ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[32]; + + if (ownersAndCount.Count < 32) + { + dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[ownersAndCount.Count]; + } + + + int num = 0; + foreach (LLUUID owner in ownersAndCount.Keys) + { + dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock(); + dataBlock[num].Count = ownersAndCount[owner]; + dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added + dataBlock[num].OnlineStatus = true; //TODO: fix me later + dataBlock[num].OwnerID = owner; + + num++; + } + + ParcelObjectOwnersReplyPacket pack = new ParcelObjectOwnersReplyPacket(); + pack.Data = dataBlock; + remote_client.OutPacket(pack); + } + } + #endregion + + #region Object Returning + public void returnObject(SceneObject obj) + { + } + public void returnLandObjects(int type, LLUUID owner) + { + + } + #endregion + + #region Object Adding/Removing from Parcel + public void resetLandPrimCounts() + { + landData.groupPrims = 0; + landData.ownerPrims = 0; + landData.otherPrims = 0; + landData.selectedPrims = 0; + primsOverMe.Clear(); + } + + public void addPrimToCount(SceneObject obj) + { + LLUUID prim_owner = obj.rootPrimitive.OwnerID; + int prim_count = obj.primCount; + + if (obj.isSelected) + { + landData.selectedPrims += prim_count; + } + else + { + if (prim_owner == landData.ownerID) + { + landData.ownerPrims += prim_count; + } + else + { + landData.otherPrims += prim_count; + } + } + + primsOverMe.Add(obj); + + } + + public void removePrimFromCount(SceneObject obj) + { + if (primsOverMe.Contains(obj)) + { + LLUUID prim_owner = obj.rootPrimitive.OwnerID; + int prim_count = obj.primCount; + + if (prim_owner == landData.ownerID) + { + landData.ownerPrims -= prim_count; + } + else if (prim_owner == landData.groupID) + { + landData.groupPrims -= prim_count; + } + else + { + landData.otherPrims -= prim_count; + } + + primsOverMe.Remove(obj); + } + } + #endregion + + #endregion + + + } + #endregion +} -- cgit v1.1