private void spawnParticles(Vec3i voxelPos, EnumVoxelMaterial voxelMat, IPlayer byPlayer) { float temp = workItemStack.Collectible.GetTemperature(Api.World, workItemStack); if (voxelMat == EnumVoxelMaterial.Metal && temp > 800) { bigMetalSparks.MinPos = Pos.ToVec3d().AddCopy(voxelPos.X / 16f, voxYOff + voxelPos.Y / 16f + 0.0625f, voxelPos.Z / 16f); bigMetalSparks.AddPos.Set(1 / 16f, 0, 1 / 16f); bigMetalSparks.VertexFlags = (byte)GameMath.Clamp((int)(temp - 700) / 2, 32, 128); Api.World.SpawnParticles(bigMetalSparks, byPlayer); smallMetalSparks.MinPos = Pos.ToVec3d().AddCopy(voxelPos.X / 16f, voxYOff + voxelPos.Y / 16f + 0.0625f, voxelPos.Z / 16f); smallMetalSparks.VertexFlags = (byte)GameMath.Clamp((int)(temp - 770) / 3, 32, 128); smallMetalSparks.AddPos.Set(1 / 16f, 0, 1 / 16f); Api.World.SpawnParticles(smallMetalSparks, byPlayer); } if (voxelMat == EnumVoxelMaterial.Slag) { slagPieces.Color = workItemStack.Collectible.GetRandomColor(Api as ICoreClientAPI, workItemStack); slagPieces.MinPos = Pos.ToVec3d().AddCopy(voxelPos.X / 16f, voxYOff + voxelPos.Y / 16f + 0.0625f, voxelPos.Z / 16f); Api.World.SpawnParticles(slagPieces, byPlayer); } }
public virtual void OnSplit(Vec3i voxelPos) { if (Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z] == (byte)EnumVoxelMaterial.Slag) { for (int dx = -1; dx <= 1; dx++) { for (int dz = -1; dz <= 1; dz++) { int x = voxelPos.X + dx; int z = voxelPos.Z + dz; if (x < 0 || z < 0 || x >= 16 || z >= 16) { continue; } if (Voxels[x, voxelPos.Y, z] == (byte)EnumVoxelMaterial.Slag) { Voxels[x, voxelPos.Y, z] = 0; } } } } Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z] = 0; }
internal Cuboidf[] GetSelectionBoxes(Vec3i forSize, EnumCircuitSelectionType selType, IPlayer forPlayer = null) { if (currentSelectionType == selType && ((forSize?.Equals(currentSelectionSize)).GetValueOrDefault(false) || (forSize == null && currentSelectionSize == null)) && !selectionBoxesDidChanged) { return(selectionBoxesVoxels); } switch (selType) { case EnumCircuitSelectionType.PlaceWire: GenerateSelectionVoxelBoxes(new Vec3i(1, 1, 1), true, true, true, false); break; case EnumCircuitSelectionType.PlaceComponent: GenerateSelectionVoxelBoxes(forSize, false, false, true, true); break; case EnumCircuitSelectionType.PlaceNothing: GenerateSelectionVoxelBoxes(new Vec3i(1, 1, 1), false, true, true, false); break; } currentSelectionSize = forSize; currentSelectionType = selType; selectionBoxesDidChanged = false; return(selectionBoxesVoxels); }
public Vec3d RandomParticlePos(BlockFacing facing = null) { Random rand = Api.World.Rand; IBlockAccessor blockAccess = Api.World.BlockAccessor; Cuboidf box = Block.GetParticleBreakBox(blockAccess, Pos, facing); if (facing == null) { return(new Vec3d( Pos.X + box.X1 + 1 / 32f + rand.NextDouble() * (box.XSize - 1 / 16f), Pos.Y + box.Y1 + 1 / 32f + rand.NextDouble() * (box.YSize - 1 / 16f), Pos.Z + box.Z1 + 1 / 32f + rand.NextDouble() * (box.ZSize - 1 / 16f) )); } else { bool haveBox = box != null; Vec3i facev = facing.Normali; Vec3d outpos = new Vec3d( Pos.X + 0.5f + facev.X / 1.9f + (haveBox && facing.Axis == EnumAxis.X ? (facev.X > 0 ? box.X2 - 1 : box.X1) : 0), Pos.Y + 0.5f + facev.Y / 1.9f + (haveBox && facing.Axis == EnumAxis.Y ? (facev.Y > 0 ? box.Y2 - 1 : box.Y1) : 0), Pos.Z + 0.5f + facev.Z / 1.9f + (haveBox && facing.Axis == EnumAxis.Z ? (facev.Z > 0 ? box.Z2 - 1 : box.Z1) : 0) ); outpos.Add( (rand.NextDouble() - 0.5) * (1 - Math.Abs(facev.X)), (rand.NextDouble() - 0.5) * (1 - Math.Abs(facev.Y)) - (facing == BlockFacing.DOWN ? 0.1f : 0f), (rand.NextDouble() - 0.5) * (1 - Math.Abs(facev.Z)) ); return(outpos); } }
private void OnHit(Vec3i voxelPos) { if (AvailableVoxels <= 0) { return; } for (int dx = -1; dx <= 1; dx++) { for (int dz = -1; dz <= 1; dz++) { Vec3i npos = voxelPos.AddCopy(dx, 0, dz); if (npos.X >= 0 && npos.X < 16 && npos.Y >= 0 && npos.Y < 16 && npos.Z >= 0 && npos.Z < 16 && !Voxels[npos.X, npos.Y, npos.Z]) { Voxels[npos.X, npos.Y, npos.Z] = true; AvailableVoxels--; if (AvailableVoxels <= 0) { return; } } } } }
public override void OnReceivedClientPacket(IPlayer player, int packetid, byte[] data) { if (packetid == (int)EnumAnvilPacket.SelectRecipe) { int num; using (MemoryStream ms = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(ms); num = reader.ReadInt32(); } selectedRecipeNumber = FindSmithingRecipeNumber(num); // Tell server to save this chunk to disk again MarkDirty(); api.World.BlockAccessor.GetChunkAtBlockPos(pos.X, pos.Y, pos.Z).MarkModified(); } if (packetid == (int)EnumAnvilPacket.OnUserOver) { Vec3i voxelPos; using (MemoryStream ms = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(ms); voxelPos = new Vec3i(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32()); } OnUseOver(player, voxelPos, new BlockSelection() { Position = pos }); } }
protected void ensureCloudTileCacheIsFresh(Vec3i tilePos) { AdjacentSims[0].EnsureCloudTileCacheIsFresh(tilePos); AdjacentSims[1].EnsureCloudTileCacheIsFresh(tilePos); AdjacentSims[2].EnsureCloudTileCacheIsFresh(tilePos); AdjacentSims[3].EnsureCloudTileCacheIsFresh(tilePos); }
public override void FromTreeAttributes(ITreeAttribute tree, IWorldAccessor worldAccessForResolve) { slaveCount = tree.GetInt("slavecount"); orientation = tree.GetString("orientation"); facing = tree.GetString("facing"); state = tree.GetInt("state", state); work = tree.GetInt("work", work); maxwork = tree.GetInt("maxwork", maxwork); if (slaveCount != 0) { for (int i = 0; i < slaveCount; i++) { slaves.Add(new Vec3i(tree.GetInt("slave" + i + "x"), tree.GetInt("slave" + i + "y"), tree.GetInt("slave" + i + "z"))); } } if (tree.HasAttribute("masterx")) { master = new Vec3i(tree.GetInt("masterx"), tree.GetInt("mastery"), tree.GetInt("masterz")); } base.FromTreeAttributes(tree, worldAccessForResolve); }
public List <Vec3i> RebuildNetwork(Vec3i pos_init, VoxelWire old_network) { if (!old_network.GotVoxelAtPos(pos_init)) { return(new List <Vec3i>()); } List <Vec3i> to_explore = new List <Vec3i>(); List <Vec3i> explored = new List <Vec3i>(); to_explore.Add(pos_init); while (to_explore.Any()) { Vec3i current_pos = to_explore.Last(); foreach (BlockFacing facing in BlockFacing.ALLFACES) { Vec3i offset_pos = current_pos.AddCopy(facing); if (old_network.GotVoxelAtPos(offset_pos) && !explored.Contains(offset_pos)) { to_explore.Add(offset_pos); } } to_explore.Remove(current_pos); explored.Add(current_pos); } //At the end, the explored list contains connected voxels return(explored); }
private static NDArray MatToNdarray <T>(Mat mat) where T : struct { switch (typeof(T).Name) { case "Byte": { var data = new Vec3b[mat.Total()]; //mat.GetArray(0, 0, data); return(Vec3bToNdarray(data, mat.Height, mat.Width, mat.Channels())); } case "Int32": unsafe { var data = new Vec3i[mat.Total()]; mat.ForEachAsVec3i((value, position) => data[*position] = *value); return(Vec3iToNdarray(data, mat.Height, mat.Width, mat.Channels())); } case "Single": unsafe { var data = new Vec3d[mat.Total()]; //mat.GetArray(0, 0, data); throw new NotImplementedException(""); } default: throw new NotImplementedException(""); } }
List <BlockPos> HalfBall(int minx, int miny, int minz, int maxx, int maxy, int maxz, int offX, int offY, int offZ, float xRadSqInv, float yRadSqInv, float zRadSqInv, float xCutRadSqInv, float yCutRadSqInv, float zCutRadSqInv) { List <BlockPos> positions = new List <BlockPos>(); size = new Vec3i(maxx - minx, maxy - miny, maxz - minz); for (int dx = minx; dx <= maxx; dx++) { for (int dy = miny; dy <= maxy; dy++) { for (int dz = minz; dz <= maxz; dz++) { if (dx * dx * xRadSqInv + dy * dy * yRadSqInv + dz * dz * zRadSqInv > 1) { continue; } if (dx * dx * xCutRadSqInv + dy * dy * yCutRadSqInv + dz * dz * zCutRadSqInv < 1) { continue; } positions.Add(new BlockPos(dx + offX, dy + offY, dz + offZ)); } } } return(positions); }
private BlockFacing GetExitingFace(Vec3i pos) { for (int i = 0; i < BlockFacing.ALLFACES.Length; i++) { BlockFacing blockSideFacing = BlockFacing.ALLFACES[i]; Vec3i planeNormal = blockSideFacing.Normali; double demon = planeNormal.X * ray.dir.X + planeNormal.Y * ray.dir.Y + planeNormal.Z * ray.dir.Z; if (demon > 0.00001) { planePosition.Set(pos).Add(blockSideFacing.PlaneCenter); pt.Set(planePosition.X - ray.origin.X, planePosition.Y - ray.origin.Y, planePosition.Z - ray.origin.Z); double t = (pt.X * planeNormal.X + pt.Y * planeNormal.Y + pt.Z * planeNormal.Z) / demon; if (t >= 0) { pHit.Set(ray.origin.X + ray.dir.X * t, ray.origin.Y + ray.dir.Y * t, ray.origin.Z + ray.dir.Z * t); if (Math.Abs(pHit.X - planePosition.X) <= 0.5 && Math.Abs(pHit.Y - planePosition.Y) <= 0.5 && Math.Abs(pHit.Z - planePosition.Z) <= 0.5) { return(blockSideFacing); } } } } return(null); }
private void Event_OnChunkDirty(Vec3i chunkCoord, IWorldChunk chunk, EnumChunkDirtyReason reason) { //api.Logger.Notification("NowDirty @{0}/{1}", chunkCoord.X, chunkCoord.Z); lock (chunksToGenLock) { if (!mapSink.IsOpened) { return; } tmpMccoord.Set(chunkCoord.X / MultiChunkMapComponent.ChunkLen, chunkCoord.Z / MultiChunkMapComponent.ChunkLen); tmpCoord.Set(chunkCoord.X, chunkCoord.Z); if (!loadedMapData.ContainsKey(tmpMccoord) && !curVisibleChunks.Contains(tmpCoord)) { return; } chunksToGen.Enqueue(new Vec2i(chunkCoord.X, chunkCoord.Z)); chunksToGen.Enqueue(new Vec2i(chunkCoord.X, chunkCoord.Z - 1)); chunksToGen.Enqueue(new Vec2i(chunkCoord.X - 1, chunkCoord.Z)); chunksToGen.Enqueue(new Vec2i(chunkCoord.X, chunkCoord.Z + 1)); chunksToGen.Enqueue(new Vec2i(chunkCoord.X + 1, chunkCoord.Z + 1)); } }
bool moveVoxelDownwards(Vec3i voxelPos, BlockFacing towardsFace, int maxDist) { int origy = voxelPos.Y; while (voxelPos.Y > 0) { voxelPos.Y--; Vec3i spos = getClosestBfs(voxelPos, towardsFace, maxDist); if (spos == null) { continue; } Voxels[voxelPos.X, origy, voxelPos.Z] = (byte)EnumVoxelMaterial.Empty; for (int y = 0; y <= spos.Y; y++) { if (Voxels[spos.X, y, spos.Z] == (byte)EnumVoxelMaterial.Empty) { Voxels[spos.X, y, spos.Z] = (byte)EnumVoxelMaterial.Metal; return(true); } } return(true); } return(false); }
public override void Initialize(ICoreAPI api) { base.Initialize(api); facing = BlockFacing.FromCode(Block.Variant["side"]); if (facing == null) { Api.World.BlockAccessor.SetBlock(0, Pos); return; } Vec3i dir = facing.Normali; anvilPos = Pos.AddCopy(dir.X * 3, 0, dir.Z * 3); togglePos = Pos.AddCopy(dir); RegisterGameTickListener(onEvery25ms, 25); capi = api as ICoreClientAPI; if (capi != null) { blockTexSource = capi.Tesselator.GetTexSource(Block); } setRenderer(); }
private void Swap(ref Vec3i a, ref Vec3i b) { Vec3i tmp = b; b = a; a = tmp; }
public override void OnReceivedClientPacket(IPlayer player, int packetid, byte[] data) { if (packetid == (int)EnumSignPacketId.SaveText) { using (MemoryStream ms = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(ms); blockName = reader.ReadString(); if (blockName == null) { blockName = ""; } } MarkDirty(true); // Tell server to save this chunk to disk again api.World.BlockAccessor.GetChunkAtBlockPos(pos.X, pos.Y, pos.Z).MarkModified(); } if (packetid == 1010) { Vec3i voxelPos; bool isBreak; BlockFacing facing; using (MemoryStream ms = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(ms); voxelPos = new Vec3i(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32()); isBreak = reader.ReadBoolean(); facing = BlockFacing.ALLFACES[reader.ReadInt16()]; } UpdateVoxel(player, player.InventoryManager.ActiveHotbarSlot, voxelPos, facing, isBreak); } }
public void EnsureCloudTileCacheIsFresh(Vec3i tilePos) { adjacentSims[0].EnsureCloudTileCacheIsFresh(tilePos); adjacentSims[1].EnsureCloudTileCacheIsFresh(tilePos); adjacentSims[2].EnsureCloudTileCacheIsFresh(tilePos); adjacentSims[3].EnsureCloudTileCacheIsFresh(tilePos); }
private void OnRemove(Vec3i voxelPos, BlockFacing facing, int radius, IPlayer byPlayer) { if (SelectedRecipe.Voxels[voxelPos.X, voxelPos.Z]) { return; } for (int dx = -(int)Math.Ceiling(radius / 2f); dx <= radius / 2; dx++) { for (int dz = -(int)Math.Ceiling(radius / 2f); dz <= radius / 2; dz++) { Vec3i offPos = voxelPos.AddCopy(dx, 0, dz); if (voxelPos.X >= 0 && voxelPos.X < 16 && voxelPos.Z >= 0 && voxelPos.Z < 16 && Voxels[offPos.X, offPos.Z]) { Voxels[offPos.X, offPos.Z] = false; double posx = pos.X + voxelPos.X / 16f; double posy = pos.Y + voxelPos.Y / 16f; double posz = pos.Z + voxelPos.Z / 16f; api.World.PlaySoundAt(new AssetLocation("sounds/player/knap" + (api.World.Rand.Next(2) > 0 ? 1 : 2)), posx, posy, posz, byPlayer, true, 12, 1); } } } }
public override void FromTreeAttributes(ITreeAttribute tree, IWorldAccessor worldForResolving) { GrowTries = tree.GetInt("growTries"); if (tree.HasAttribute("rootOffX")) { RootOff = new Vec3i(tree.GetInt("rootOffX"), tree.GetInt("rootOffY"), tree.GetInt("rootOffZ")); } initCustomBehaviors(null, false); base.FromTreeAttributes(tree, worldForResolving); SideGrowth = tree.GetInt("sideGrowth", 0); if (tree.HasAttribute("parentX")) { ParentOff = new Vec3i(tree.GetInt("parentX"), tree.GetInt("parentY"), tree.GetInt("parentZ")); } InitAfterWorldGen = tree.GetBool("initAfterWorldGen"); lastGrowthAttemptTotalDays = tree.GetDouble("lastGrowthAttemptTotalDays"); if (Api != null) { updateProperties(); } }
/// <summary> /// Attempts to add the new model. /// </summary> /// <param name="capi">The core client API</param> /// <param name="modeldata">The model to add</param> /// <param name="modelOrigin">The origin point of the model.</param> /// <param name="frustumCullSphere">The culling sphere.</param> /// <returns>The location of the model (and the data) in the pool.</returns> public ModelDataPoolLocation TryAdd(ICoreClientAPI capi, MeshData modeldata, Vec3i modelOrigin, Sphere frustumCullSphere) { if (poolLocations.Count >= MaxPartsPerPool) { return(null); } // Can't add a model data to far away from our baseposition, otherwise our floating point positions // become too inaccurate if (poolOrigin != null && modelOrigin.SquareDistanceTo(poolOrigin) > 5000 * 5000) { return(null); } if (CurrentFragmentation > 0.05f) { ModelDataPoolLocation location = TrySqueezeInbetween(capi, modeldata, modelOrigin, frustumCullSphere); if (location != null) { return(location); } } return(TryAppend(capi, modeldata, modelOrigin, frustumCullSphere)); }
private void Event_ChunkDirty(Vec3i chunkCoord, IWorldChunk chunk, EnumChunkDirtyReason reason) { if (allNetworksFullyLoaded || reason == EnumChunkDirtyReason.MarkedDirty) { return; } allNetworksFullyLoaded = true; nowFullyLoaded.Clear(); foreach (var network in data.networksById.Values) { if (network.fullyLoaded) { continue; } allNetworksFullyLoaded = false; if (network.inChunks.ContainsKey(chunkCoord)) { testFullyLoaded(network); if (network.fullyLoaded) { nowFullyLoaded.Add(network); } } } for (int i = 0; i < nowFullyLoaded.Count; i++) { RebuildNetwork(nowFullyLoaded[i]); } }
//Called ClientSide public void OnUseOver(IPlayer byPlayer, BlockSelection blockSel, bool mouseBreakMode) { Cuboidf[] boxes = Circuit.GetCurrentSelectionBoxes(); //If true, something is wrong with selection boxes or the board was selected. if (blockSel.SelectionBoxIndex >= boxes.Length) { return; } //From the hit position and the face we can infere a voxel position without using selection box index //It works but could be refined Vec3f rotation = SignalsUtils.FacingToRotation(this.orientation, this.facing); Vec3f hitPos = blockSel.HitPosition.ToVec3f().Mul(16); BlockFacing selectionFacing = blockSel.Face; //We translate using the normal to avoid rounding and precision issues Vec3f hitPos2 = hitPos.AddCopy(selectionFacing.Normalf.NormalizedCopy().Mul(-0.5f)); //We need to apply rotation now RotateFromBEtoCircuit(ref hitPos2, ref selectionFacing, new Vec3f(8, 8, 8)); Vec3i voxelPos = new Vec3i((int)Math.Floor(hitPos2.X), (int)Math.Floor(hitPos2.Y), (int)Math.Floor(hitPos2.Z)); Cuboidf box = boxes[blockSel.SelectionBoxIndex]; Vec3i voxelBoxPos = new Vec3i((int)Math.Floor(box.MinX * 16), (int)Math.Floor(box.MinY * 16), (int)Math.Floor(box.MinZ * 16)); OnUseOver(byPlayer, voxelPos, voxelBoxPos, selectionFacing, mouseBreakMode); }
//Notifies the server that the block have been interacted with public void SendUseOverPacket(IPlayer byPlayer, Vec3i voxelPos, Vec3i voxelBoxPos, BlockFacing facing, bool mouseMode) { byte[] data; using (MemoryStream ms = new MemoryStream()) { BinaryWriter writer = new BinaryWriter(ms); writer.Write(voxelPos.X); writer.Write(voxelPos.Y); writer.Write(voxelPos.Z); writer.Write(voxelBoxPos.X); writer.Write(voxelBoxPos.Y); writer.Write(voxelBoxPos.Z); writer.Write(mouseMode); writer.Write((ushort)facing.Index); data = ms.ToArray(); } ((ICoreClientAPI)Api).Network.SendBlockEntityPacket( Pos.X, Pos.Y, Pos.Z, (int)EnumBECircuitPacket.OnUserOver, data ); }
public override Vec3i[] GetInputPositions() { Vec3i pos1 = new Vec3i(-1, 0, 1).AddCopy(Pos.X, Pos.Y, Pos.Z); Vec3i pos2 = new Vec3i(1, 6, 1).AddCopy(Pos.X, Pos.Y, Pos.Z); return(new Vec3i[] { pos1, pos2 }); }
private bool OnRemove(Vec3i voxelPos, BlockFacing facing, int radius) { bool didremove = false; int layer = NextNotMatchingRecipeLayer(); if (voxelPos.Y != layer) { return(didremove); } for (int dx = -(int)Math.Ceiling(radius / 2f); dx <= radius / 2; dx++) { for (int dz = -(int)Math.Ceiling(radius / 2f); dz <= radius / 2; dz++) { Vec3i offPos = voxelPos.AddCopy(dx, 0, dz); if (offPos.X >= 0 && offPos.X < 16 && offPos.Y >= 0 && offPos.Y <= 16 && offPos.Z >= 0 && offPos.Z < 16) { bool hadVoxel = Voxels[offPos.X, offPos.Y, offPos.Z]; didremove |= hadVoxel; Voxels[offPos.X, offPos.Y, offPos.Z] = false; if (hadVoxel) { AvailableVoxels++; } } } } return(didremove); }
private bool OnRemove(Vec3i voxelPos, int radius) { // Required voxel, don't let the player break it if (SelectedRecipe == null || SelectedRecipe.Voxels[voxelPos.X, 0, voxelPos.Z]) { return(false); } for (int dx = -(int)Math.Ceiling(radius / 2f); dx <= radius / 2; dx++) { for (int dz = -(int)Math.Ceiling(radius / 2f); dz <= radius / 2; dz++) { Vec3i offPos = voxelPos.AddCopy(dx, 0, dz); if (voxelPos.X >= 0 && voxelPos.X < 16 && voxelPos.Z >= 0 && voxelPos.Z < 16 && Voxels[offPos.X, offPos.Z]) { Voxels[offPos.X, offPos.Z] = false; lastRemovedLocalPos.Set(Pos.X + voxelPos.X / 16f, Pos.Y + voxelPos.Y / 16f, Pos.Z + voxelPos.Z / 16f); return(true); } } } return(false); }
public virtual void RegenCloudTileCache(Vec3i tileOffset) { tilesPerRegion = (int)Math.Ceiling((float)api.World.BlockAccessor.RegionSize / ws.CloudTileSize) + 2 * NoisePadding; CloudDensityNoiseCache = new double[tilesPerRegion, tilesPerRegion]; lastTileX = cloudTilebasePosX + tileOffset.X; lastTileZ = cloudTilebasePosZ + tileOffset.Z; double timeAxis = api.World.Calendar.TotalDays / 10.0; if (LocationalCloudThicknessGen == null) { for (int dx = 0; dx < tilesPerRegion; dx++) { for (int dz = 0; dz < tilesPerRegion; dz++) { CloudDensityNoiseCache[dx, dz] = 0; } } } else { for (int dx = 0; dx < tilesPerRegion; dx++) { for (int dz = 0; dz < tilesPerRegion; dz++) { double x = (lastTileX + dx - tilesPerRegion / 2 - NoisePadding) / 20.0; double z = (lastTileZ + dz - tilesPerRegion / 2 - NoisePadding) / 20.0; CloudDensityNoiseCache[dx, dz] = GameMath.Clamp(LocationalCloudThicknessGen.Noise(x, z, timeAxis), 0, 1); } } } }
private void Event_ChunkDirty(Vec3i chunkCoord, IWorldChunk chunk, EnumChunkDirtyReason reason) { long index3d = MapUtil.Index3dL(chunkCoord.X, chunkCoord.Y, chunkCoord.Z, chunkMapSizeX, chunkMapSizeZ); ChunkRooms chunkrooms; Cuboidi cuboid; FastSetOfLongs set = new FastSetOfLongs(); set.Add(index3d); lock (roomsByChunkIndexLock) { roomsByChunkIndex.TryGetValue(index3d, out chunkrooms); if (chunkrooms != null) { set.Add(index3d); for (int i = 0; i < chunkrooms.Rooms.Count; i++) { cuboid = chunkrooms.Rooms[i].Location; int x1 = cuboid.Start.X / chunksize; int x2 = cuboid.End.X / chunksize; int y1 = cuboid.Start.Y / chunksize; int y2 = cuboid.End.Y / chunksize; int z1 = cuboid.Start.Z / chunksize; int z2 = cuboid.End.Z / chunksize; set.Add(MapUtil.Index3dL(x1, y1, z1, chunkMapSizeX, chunkMapSizeZ)); if (z2 != z1) { set.Add(MapUtil.Index3dL(x1, y1, z2, chunkMapSizeX, chunkMapSizeZ)); } if (y2 != y1) { set.Add(MapUtil.Index3dL(x1, y2, z1, chunkMapSizeX, chunkMapSizeZ)); if (z2 != z1) { set.Add(MapUtil.Index3dL(x1, y2, z2, chunkMapSizeX, chunkMapSizeZ)); } } if (x2 != x1) { set.Add(MapUtil.Index3dL(x2, y1, z1, chunkMapSizeX, chunkMapSizeZ)); if (z2 != z1) { set.Add(MapUtil.Index3dL(x2, y1, z2, chunkMapSizeX, chunkMapSizeZ)); } if (y2 != y1) { set.Add(MapUtil.Index3dL(x2, y2, z1, chunkMapSizeX, chunkMapSizeZ)); if (z2 != z1) { set.Add(MapUtil.Index3dL(x2, y2, z2, chunkMapSizeX, chunkMapSizeZ)); } } } } } foreach (long index in set) { roomsByChunkIndex.Remove(index); } } }
private bool RequiresStand(BlockPos pos, Vec3i vector) { BlockMPBase block = Api.World.BlockAccessor.GetBlock(pos.X + vector.X, pos.Y + vector.Y, pos.Z + vector.Z) as BlockMPBase; if (block == null) { return(true); } BlockPos sidePos = new BlockPos(pos.X + vector.X, pos.Y + vector.Y, pos.Z + vector.Z); BEBehaviorMPBase bemp = Api.World.BlockAccessor.GetBlockEntity(sidePos)?.GetBehavior <BEBehaviorMPBase>(); if (bemp == null) { return(true); } BEBehaviorMPAxle bempaxle = bemp as BEBehaviorMPAxle; if (bempaxle == null) { if (bemp is BEBehaviorMPBrake || bemp is BEBehaviorMPCreativeRotor) { BlockFacing side = BlockFacing.FromNormal(vector); if (side != null && block.HasMechPowerConnectorAt(Api.World, sidePos, side.Opposite)) { return(false); } } return(true); } if (IsAttachedToBlock(Api.World.BlockAccessor, block, sidePos)) { return(false); } return(bempaxle.RequiresStand(sidePos, vector)); }
public void TickPhysicsInfluence( bool allowSplashes ) { if( volumeBody == null ) return; EngineRandom random = World.Instance.Random; List<SubmergedCheckItem> submergedItems = listSubmergedCheckItemAllocator.Alloc(); Vec2 halfSize = Size * .5f; Bounds volumeBounds = new Bounds( new Vec3( Position.X - halfSize.X, Position.Y - halfSize.Y, Position.Z - physicsHeight ), new Vec3( Position.X + halfSize.X, Position.Y + halfSize.Y, Position.Z ) ); Body[] bodies = PhysicsWorld.Instance.VolumeCast( volumeBounds, (int)ContactGroup.CastOnlyDynamic ); foreach( Body body in bodies ) { if( body.Static ) continue; Mat3 bodyRotation = body.Rotation.ToMat3(); foreach( Shape shape in body.Shapes ) { if( shape.ContactGroup == (int)ContactGroup.NoContact ) continue; Vec3 shapePosition = body.Position + bodyRotation * shape.Position; float volume = shape.Volume; switch( shape.ShapeType ) { case Shape.Type.Box: { BoxShape boxShape = (BoxShape)shape; Quat shapeRotation = body.Rotation; if( !shape.IsIdentityTransform ) shapeRotation *= shape.Rotation; Vec3 halfD = boxShape.Dimensions * .5f; float r = Math.Min( Math.Min( halfD.X, halfD.Y ), halfD.Z ); Vec3i stepsCount = new Vec3i( 1, 1, 1 ); if( halfD.X > r * .3f ) stepsCount.X = 2; if( halfD.Y > r * .3f ) stepsCount.Y = 2; if( halfD.Z > r * .3f ) stepsCount.Z = 2; for( int z = 0; z < stepsCount.Z; z++ ) { for( int y = 0; y < stepsCount.Y; y++ ) { for( int x = 0; x < stepsCount.X; x++ ) { Vec3 localPos = Vec3.Zero; if( stepsCount.X == 2 ) localPos.X = ( x == 0 ) ? ( -halfD.X + r ) : ( halfD.X - r ); if( stepsCount.Y == 2 ) localPos.Y = ( y == 0 ) ? ( -halfD.Y + r ) : ( halfD.Y - r ); if( stepsCount.X == 2 ) localPos.Z = ( z == 0 ) ? ( -halfD.Z + r ) : ( halfD.Z - r ); Vec3 pos = shapePosition + shapeRotation * localPos; submergedItems.Add( GetSphereSubmergedCoef( new Sphere( pos, r ) ) ); } } } } break; case Shape.Type.Capsule: { CapsuleShape capsuleShape = (CapsuleShape)shape; float r = capsuleShape.Radius; float l = capsuleShape.Length; Quat shapeRotation = body.Rotation; if( !shape.IsIdentityTransform ) shapeRotation *= shape.Rotation; Vec3 pos; pos = shapePosition + shapeRotation * new Vec3( 0, 0, -l * .5f ); submergedItems.Add( GetSphereSubmergedCoef( new Sphere( pos, r ) ) ); pos = shapePosition + shapeRotation * new Vec3( 0, 0, l * .5f ); submergedItems.Add( GetSphereSubmergedCoef( new Sphere( pos, r ) ) ); } break; case Shape.Type.Sphere: { SphereShape sphereShape = (SphereShape)shape; float r = sphereShape.Radius; submergedItems.Add( GetSphereSubmergedCoef( new Sphere( shapePosition, r ) ) ); } break; case Shape.Type.Mesh: { MeshShape meshShape = (MeshShape)shape; Bounds b; if( meshShape.GetDataBounds( out b ) ) { float r = b.GetRadius(); submergedItems.Add( GetSphereSubmergedCoef( new Sphere( shapePosition, r ) ) ); } } break; } if( submergedItems.Count == 0 ) continue; //calculate summary submerged coefficient and force center float submergedCoef; Vec3 submergedCenter; { if( submergedItems.Count != 1 ) { submergedCoef = 0; submergedCenter = Vec3.Zero; float len = 0; foreach( SubmergedCheckItem item in submergedItems ) len += item.coef; if( len != 0 ) { float invLen = 1.0f / len; foreach( SubmergedCheckItem item in submergedItems ) { submergedCoef += item.coef; submergedCenter += item.center * ( item.coef * invLen ); } submergedCoef /= (float)submergedItems.Count; } } else { submergedCoef = submergedItems[ 0 ].coef; submergedCenter = submergedItems[ 0 ].center; } } //create splashes if( allowSplashes && submergedItems.Count != 0 ) { const float minimalBodyVelocity = 3; const float minimalTimeBetweenSplashes = .25f; float length = body.LinearVelocity.LengthFast(); if( length > minimalBodyVelocity ) { int index = bodiesSplashOffTime.FindIndex( delegate( SplashOffItem item ) { return item.body == body; } ); if( index == -1 ) { bool created = false; Vec3 splashPosition = Vec3.Zero; foreach( SubmergedCheckItem item in submergedItems ) { if( item.coef > 0 && item.coef < 1 ) { Vec3 pos = new Vec3( item.center.X, item.center.Y, Position.Z ); //no create splashes too much nearly if( created && ( pos - splashPosition ).LengthFast() < .1f ) continue; //create splash splashPosition = pos; CreateSplash( WaterPlaneType.SplashTypes.Body, splashPosition ); created = true; } } if( created ) { SplashOffItem item; item.body = body; item.remainingTime = minimalTimeBetweenSplashes; bodiesSplashOffTime.Add( item ); } } } } submergedItems.Clear(); if( submergedCoef == 0 ) continue; //add forces float shapeDensity = GetShapeInfluenceDensity( shape ); if( shapeDensity == 0 ) continue; float densityCoef = Type.PhysicsDensity / shapeDensity; float mass = volume * shape.Density; //buoyancy force { const float roughnessLinearCoef = .5f; float coef = densityCoef * submergedCoef; coef += random.NextFloatCenter() * roughnessLinearCoef; Vec3 vector = -PhysicsWorld.Instance.Gravity * ( mass * coef ); body.AddForce( ForceType.GlobalAtGlobalPos, TickDelta, vector, submergedCenter ); } //linear damping { float constCoef = 2; float coef = submergedCoef * constCoef * densityCoef; Vec3 vector = -body.LinearVelocity * mass * coef; body.AddForce( ForceType.GlobalAtGlobalPos, TickDelta, vector, submergedCenter ); } //angular damping { const float constCoef = .5f; const float roughnessAngularCoef = .25f; float coef = submergedCoef * constCoef; Vec3 vector = -body.AngularVelocity * mass * coef; float roughnessX = random.NextFloatCenter() * roughnessAngularCoef; float roughnessY = random.NextFloatCenter() * roughnessAngularCoef; float roughnessZ = random.NextFloatCenter() * roughnessAngularCoef; vector += new Vec3( roughnessX, roughnessY, roughnessZ ); body.AddForce( ForceType.GlobalTorque, TickDelta, vector, Vec3.Zero ); } } } listSubmergedCheckItemAllocator.Free( submergedItems ); }
public static extern void core_Mat_push_back_Vec3i(IntPtr self, Vec3i v);