/// <summary> /// voxel modify check event before really undo and redo. Call by BSVoxelModify /// </summary> bool OnCheckVoxelModify(int opType, IntVector3[] indexes, BSVoxel[] voxels, BSVoxel[] oldvoxels, EBSBrushMode mode, IBSDataSource ds) { if (IsGod) { return(true); } if (Pathea.PeCreature.Instance.mainPlayer == null) { return(false); } bool result = true; if (mode == EBSBrushMode.Add) { Dictionary <int, int> items = new Dictionary <int, int>(); // Calculate the needed items; int adder = 1; foreach (BSVoxel voxel in voxels) { int id = 0; if (ds == BuildingMan.Blocks) { if (voxel.IsExtendable()) { if (!voxel.IsExtendableRoot()) { id = GetBlockItemProtoID((byte)(voxel.materialType >> 2)); adder = 1; } else { adder = 0; } } else { id = GetBlockItemProtoID(voxel.materialType); } } else if (ds == BuildingMan.Voxels) { id = GetVoxelItemProtoID(voxel.materialType); } if (id <= 0) { continue; } if (id != 0) { if (items.ContainsKey(id)) { items[id] += adder; } else { items.Add(id, adder); } } } _costsItems = items; float divisor = 1.0f; if (ds == BuildingMan.Blocks) { divisor = (float)(1 << BSBlock45Data.s_ScaleInverted); } // Has player enough items ? Pathea.PackageCmpt pkg = Pathea.PeCreature.Instance.mainPlayer.GetCmpt <Pathea.PackageCmpt>(); _playerItems.Clear(); foreach (KeyValuePair <int, int> kvp in items) { _playerItems.Add(kvp.Key, pkg.GetItemCount(kvp.Key)); if (pkg.GetItemCount(kvp.Key) < Mathf.CeilToInt(kvp.Value / divisor)) { result = false; } } // now delete if (result) { if (GameConfig.IsMultiMode) { if (null == PlayerNetwork.mainPlayer) { return(false); } if (!Pathea.PeGameMgr.IsMultiCoop && VArtifactUtil.IsInTownBallArea(PlayerNetwork.mainPlayer._pos)) { new PeTipMsg(PELocalization.GetString(8000864), PeTipMsg.EMsgLevel.Warning); return(false); } //if (!PlayerNetwork.OnLimitBoundsCheck(brushBound)) //{ // new PeTipMsg(PELocalization.GetString(8000864), PeTipMsg.EMsgLevel.Warning); // return false; //} PlayerNetwork.mainPlayer.RequestRedo(opType, indexes, oldvoxels, voxels, mode, ds.DataType, ds.Scale); DigTerrainManager.BlockClearGrass(ds, indexes); return(true); } else { string debug_log = ""; foreach (KeyValuePair <int, int> kvp in items) { if (pkg.Destory(kvp.Key, Mathf.CeilToInt(kvp.Value / divisor))) { debug_log += "\r\n Rmove Item from player package ID[" + kvp.Key.ToString() + "]" + " count - " + kvp.Value.ToString(); } } if (ds == BuildingMan.Blocks) { for (int i = 0; i < indexes.Length; i++) { Vector3 pos = new Vector3(indexes[i].x * ds.Scale, indexes[i].y * ds.Scale, indexes[i].z * ds.Scale) - ds.Offset; PeGrassSystem.DeleteAtPos(pos); PeGrassSystem.DeleteAtPos(new Vector3(pos.x, pos.y - 1, pos.z)); //PeGrassSystem.DeleteAtPos(new Vector3(pos.x, pos.y + 1, pos.z)); } } else if (ds == BuildingMan.Voxels) { for (int i = 0; i < indexes.Length; i++) { Vector3 pos = new Vector3(indexes[i].x, indexes[i].y, indexes[i].z); PeGrassSystem.DeleteAtPos(pos); PeGrassSystem.DeleteAtPos(new Vector3(pos.x, pos.y - 1, pos.z)); //PeGrassSystem.DeleteAtPos(new Vector3(pos.x, pos.y + 1, pos.z)); } } //Debug.LogWarning(debug_log); } } else { new PeTipMsg(PELocalization.GetString(821000001), PeTipMsg.EMsgLevel.Warning); } } else if (mode == EBSBrushMode.Subtract) { Dictionary <int, int> items = new Dictionary <int, int>(); // Calculate the needed items; int adder = 1; foreach (BSVoxel voxel in oldvoxels) { int id = 0; if (ds == BuildingMan.Blocks) { if (voxel.IsExtendable()) { if (!voxel.IsExtendableRoot()) { id = GetBlockItemProtoID((byte)(voxel.materialType >> 2)); adder = 1; } else { adder = 0; } } else { if (!BuildingMan.Blocks.VoxelIsZero(voxel, 0)) { id = GetBlockItemProtoID((byte)(voxel.materialType)); } } } else if (ds == BuildingMan.Voxels) { if (!BuildingMan.Voxels.VoxelIsZero(voxel, 1)) { id = GetVoxelItemProtoID(voxel.materialType); } } if (id <= 0) { continue; } if (items.ContainsKey(id)) { items[id] += adder; } else { items.Add(id, adder); } } float divisor = 1.0f; if (ds == BuildingMan.Blocks) { divisor = (float)(1 << BSBlock45Data.s_ScaleInverted); } // Has player enough package ? Pathea.PlayerPackageCmpt pkg = Pathea.PeCreature.Instance.mainPlayer.GetCmpt <Pathea.PlayerPackageCmpt>(); MaterialItem[] array = new MaterialItem[items.Count]; int i = 0; foreach (KeyValuePair <int, int> kvp in items) { array[i] = new MaterialItem() { protoId = kvp.Key, count = Mathf.FloorToInt(kvp.Value / divisor) }; i++; } result = pkg.package.CanAdd(array); // Really add if (result) { if (GameConfig.IsMultiMode) { if (null == PlayerNetwork.mainPlayer) { return(false); } //if (!PlayerNetwork.OnLimitBoundsCheck(brushBound)) //{ // new PeTipMsg(PELocalization.GetString(8000864), PeTipMsg.EMsgLevel.Warning); // return false; //} PlayerNetwork.mainPlayer.RequestRedo(opType, indexes, oldvoxels, voxels, mode, ds.DataType, ds.Scale); return(true); } else { string debug_log = ""; foreach (MaterialItem mi in array) { if (mi.count != 0) { pkg.Add(mi.protoId, mi.count); } debug_log += "Add Item from player package ID[" + mi.protoId.ToString() + "]" + " count - " + mi.count.ToString() + "\r\n"; } Debug.LogWarning(debug_log); } } } if (result) { if (onVoxelMotify != null) { onVoxelMotify(indexes, voxels, oldvoxels, mode, ds); } } return(result); }
protected void ClearSubterrain() { if (null == itemBounds) { return; } if (PeGameMgr.IsMulti) { List <Vector3> grassPos = new List <Vector3>(); Bounds selfBounds = itemBounds.worldBounds; Vector3 minPos = selfBounds.min - subTerrainClearRadius * Vector3.one; Vector3 maxPos = selfBounds.max + subTerrainClearRadius * Vector3.one; for (float _x = minPos.x; _x <= maxPos.x; ++_x) { for (float _y = minPos.y; _y <= maxPos.y; ++_y) { for (float _z = minPos.z; _z <= maxPos.z; ++_z) { Vector3 pos = new Vector3(Mathf.RoundToInt(_x), Mathf.RoundToInt(_y), Mathf.RoundToInt(_z)); Vector3 outPos; if (PeGrassSystem.DeleteAtPos(pos, out outPos)) { grassPos.Add(outPos); } } } } if (grassPos.Count == 0) { return; } byte[] grassData = PETools.Serialize.Export((w) => { w.Write(grassPos.Count); for (int i = 0; i < grassPos.Count; i++) { BufferHelper.Serialize(w, grassPos[i]); } }); if (null != PlayerNetwork.mainPlayer) { PlayerNetwork.mainPlayer.RPCServer(EPacketType.PT_InGame_ClearGrass, grassData); } } else { Bounds selfBounds = itemBounds.worldBounds; Vector3 minPos = selfBounds.min - subTerrainClearRadius * Vector3.one; Vector3 maxPos = selfBounds.max + subTerrainClearRadius * Vector3.one; for (float _x = minPos.x; _x <= maxPos.x; ++_x) { for (float _y = minPos.y; _y <= maxPos.y; ++_y) { for (float _z = minPos.z; _z <= maxPos.z; ++_z) { PeGrassSystem.DeleteAtPos(new Vector3(Mathf.RoundToInt(_x), Mathf.RoundToInt(_y), Mathf.RoundToInt(_z))); } } } } }