public static void Postfix(Block __instance, ItemSlot slot, EntityAgent byEntity) { if (byEntity.World.Side.IsClient()) { if (!(slot is DummySlot) && slot is ItemSlotOffhand) { return; } if ((byEntity.World as ClientMain).ElapsedMilliseconds % 4 == 0) { var player = (byEntity as EntityPlayer).Player; if (!KnownBroken.Contains(__instance.GetType()) && player?.CurrentBlockSelection != null && slot?.Itemstack != null) { SetBlockRedirect.setBlock = false; var blockSel = player.CurrentBlockSelection; Block onBlock = byEntity.World.BlockAccessor.GetBlock(blockSel.Position); BlockPos buildPos = blockSel.Position; if (onBlock == null || !onBlock.IsReplacableBy(__instance)) { buildPos = buildPos.Offset(blockSel.Face); blockSel.DidOffset = true; } string fail = ""; bool works = false; try { works = __instance.TryPlaceBlock(byEntity.World, player, slot.Itemstack, blockSel, ref fail); } catch (Exception) { KnownBroken.Add(__instance.GetType()); } if (blockSel.DidOffset) { buildPos.Offset(blockSel.Face.Opposite); blockSel.DidOffset = false; } if (!works) { SetBlockRedirect.blockId = 0; } SetBlockRedirect.setBlock = true; } else { SetBlockRedirect.blockId = 0; } } } }
public void PlaceBlock() { MouseOverObject moo = SharpCraft.Instance.MouseOverObject; if (moo.hit != HitType.Block) { return; } ItemStack stack = GetEquippedItemStack(); if (!(stack?.Item is ItemBlock itemBlock)) { return; } Block air = BlockRegistry.GetBlock <BlockAir>(); Block glass = BlockRegistry.GetBlock <BlockGlass>(); Block grass = BlockRegistry.GetBlock <BlockGrass>(); Block dirt = BlockRegistry.GetBlock <BlockDirt>(); BlockState clickedState = World.GetBlockState(moo.blockPos); bool replacing; BlockPos pos = (replacing = clickedState.Block.IsReplaceable && itemBlock.Block != clickedState.Block) ? moo.blockPos : moo.blockPos.Offset(moo.sideHit); Block heldBlock = itemBlock.Block; AxisAlignedBB blockBb = heldBlock.BoundingBox.offset(pos.ToVec()); if (!replacing && World.GetBlockState(pos).Block != air || World.GetIntersectingEntitiesBBs(blockBb).Count > 0 && heldBlock.IsSolid) { return; } BlockPos posUnder = pos.Offset(FaceSides.Down); BlockState stateUnder = World.GetBlockState(posUnder); BlockState stateAbove = World.GetBlockState(pos.Offset(FaceSides.Up)); if (stateUnder.Block == grass && heldBlock != glass && heldBlock.IsSolid) { World.SetBlockState(posUnder, dirt.GetState()); } if (stateAbove.Block != air && stateAbove.Block != glass && heldBlock == grass && stateAbove.Block.IsSolid) { World.SetBlockState(pos, dirt.GetState()); } else { World.SetBlockState(pos, heldBlock.GetState(stack.Meta)); } stack.Count--; SharpCraft.Instance.GetMouseOverObject(); }
public static IMechanicalPowerDevice getNeighbourDevice(IWorldAccessor world, BlockPos pos, BlockFacing facing, bool connected) { if (facing == null) { return(null); } BlockEntity te = world.BlockAccessor.GetBlockEntity(pos.Offset(facing)); if (te is IMechanicalPowerDevice) { IMechanicalPowerDevice mechdevice = (IMechanicalPowerDevice)te; if (!mechdevice.exists()) { return(null); } if (!connected && mechdevice.hasConnectorAt(facing.GetOpposite())) { return(mechdevice); } if (connected && mechdevice.isConnectedAt(facing.GetOpposite())) { return(mechdevice); } } return(null); }
public int FindGround(BlockPos pos) { int seekLimit = 256; int y = 0; if (GetBlock(pos).PhysicsMaterial.IsSolid) { while (GetBlock(pos.Offset(0, y + 1, 0)).PhysicsMaterial.IsSolid) { y++; } } else { while (seekLimit-- > 0 && !GetBlock(pos.Offset(0, y, 0)).PhysicsMaterial.IsSolid) { y--; } } return(pos.Y + y); }
public int GetHeightAtPos(int x, int z) { BlockPos pos = new BlockPos(x, 256, z); for (int y = ChunkHeight - 1; y >= 0; y--) { if (!IsAir(pos = pos.Offset(FaceSides.Down))) { return(y + 1); } } return(0); }
public static BlockPos GetRecommendedPos(this BlockSelection sel) { BlockPos adjPos = sel.Position.Copy(); return(adjPos.Offset(sel.Face)); }
public override void Update() { _ticksLast = _ticks; if (OnGround) { _ticks = (_ticks + 1) % 90; if (_ticksLast > _ticks) { _ticksLast = _ticks - 1; } } LastPos = Pos; Motion.Y -= 0.04f * Gravity; Move(); Motion.Xz *= 0.8664021f; List <AxisAlignedBb> bbs = SharpCraft.Instance.World.GetBlockCollisionBoxes(BoundingBox); if (bbs.Count > 0) { BlockPos bp = new BlockPos(Pos); FaceSides lastFace = FaceSides.Up; bool blocksAround = FaceSides.YPlane.All(face => World.IsAir(bp.Offset(lastFace = face))) && World.IsAir(bp.Offset(lastFace = FaceSides.Up)) && World.IsAir(bp.Offset(lastFace = FaceSides.Down)); //has to be in this order if (!blocksAround) { Motion += lastFace.ToVec() * 0.1f; } } if (OnGround) { Motion.Xz *= 0.6676801f; } if (++_entityAge >= 20 * 50 * 60 + 10) //stay on ground for a minute, 20 ticks as a pick up delay { SetDead(); return; } if (_entityAge < 5) { return; } List <EntityItem> inAttractionArea = World.Entities.OfType <EntityItem>().Where(e => e != this && e.IsAlive && e._stack.ItemSame(_stack)).OrderByDescending(e => e._stack.Count).ToList(); float attractionRange = 1.8F; float mergeRange = 0.15F; foreach (EntityItem entity in inAttractionArea) { if (_stack.IsEmpty || entity._stack.IsEmpty || entity._stack.Count == entity._stack.Item.GetMaxStackSize()) { continue; } Vector3 distanceVector = entity.Pos - Pos; float distance = distanceVector.Length; if (distance >= attractionRange) { continue; } int ammountToTake = Math.Min(_stack.Item.GetMaxStackSize() - _stack.Count, entity._stack.Count); if (ammountToTake == 0) { continue; } if (distance <= mergeRange) { //Motion -= entity.Motion * MathUtil.Remap(entity.stack.Count / (float)stack.Count, 1, 64, 1, 3); //entity.Motion -= Motion * MathUtil.Remap(stack.Count / (float)entity.stack.Count, 1, 64, 1, 3); entity._stack.Count -= ammountToTake; if (entity._stack.IsEmpty) { entity.SetDead(); } _stack.Count += ammountToTake; _entityAge = 3; entity._entityAge = 1; continue; } distanceVector.Normalize(); float distanceMul = (float)Math.Sqrt(1 - distance / attractionRange); if (distanceMul > 0.8) { distanceMul = ((1 - distanceMul) / 0.2F) * 0.6F + 0.2F; } Vector3 baseForce = distanceVector * 0.02f * distanceMul * MathUtil.Remap(_stack.Count / (float)entity._stack.Count, 1, entity._stack.Item.GetMaxStackSize(), 2, 5); Motion += baseForce * entity._stack.Count / Math.Max(entity._stack.Count, _stack.Count); entity.Motion -= baseForce * _stack.Count / Math.Max(entity._stack.Count, _stack.Count); } if (_entityAge < 15 || !IsAlive) { return; } //TODO change this for multiplayer IEnumerable <EntityPlayerSp> players = World.Entities.OfType <EntityPlayerSp>() .OrderBy(entity => Vector3.Distance(entity.Pos, Pos)) .Where(e => Vector3.Distance(e.Pos, Pos) <= attractionRange); foreach (EntityPlayerSp player in players) { if (!player.CanPickUpStack(_stack)) { continue; } Vector3 attrTarget = player.Pos; attrTarget.Y += player.GetCollisionBoundingBox().Size.Y / 2; Vector3 distanceVector = attrTarget - Pos; if (distanceVector.Length <= 0.35f) { if (player.OnPickup(_stack)) { SetDead(); } Motion *= -1f; } Motion = distanceVector.Normalized() * 0.45f; } if (_stack.IsEmpty) { SetDead(); } }
public void BuildChunkModelNow() { if (ModelBuilding || !QueuedForModelBuild) { return; } ModelBuilding = true; //ConcurrentDictionary<Shader<ModelBlock>, List<RawQuad>> modelRaw = new ConcurrentDictionary<Shader<ModelBlock>, List<RawQuad>>(); //List<RawQuad> quads; Stopwatch sw = Stopwatch.StartNew(); //this is just a debug thing.... var air = BlockRegistry.GetBlock <BlockAir>(); var vertexes = new List <float>(); var normals = new List <float>(); var uvs = new List <float>(); object locker = new object(); //generate the model - fill MODEL_RAW Enumerable.Range(0, ChunkHeight).AsParallel().ForAll(y => { for (int x = 0; x < ChunkSize; x++) { for (int z = 0; z < ChunkSize; z++) { BlockPos worldPos = new BlockPos(x + Pos.WorldSpaceX(), y, z + Pos.WorldSpaceZ()); BlockState state = World.GetBlockState(worldPos); if (state.Block == air) { continue; } BlockPos localPos = new BlockPos(x, y, z); ModelBlockRaw mbr = (ModelBlockRaw)state.Model?.RawModel; if (mbr == null) { continue; } if (!state.Block.IsFullCube) { lock (locker) mbr.AppendAllVertexData(vertexes, normals, uvs, localPos); continue; } for (var index = 0; index < FaceSides.AllSides.Count; index++) { FaceSides dir = FaceSides.AllSides[index]; BlockPos worldPosO = worldPos.Offset(dir); BlockState stateO = World.GetBlockState(worldPosO); if (!(stateO.Block == air || stateO.Block.HasTransparency && !state.Block.HasTransparency) && stateO.Block.IsFullCube) { continue; } lock (locker) { mbr.AppendVertexDataForSide(dir, vertexes, normals, uvs, localPos); //mbr.AppendNormalsForSide(dir, normals); //mbr.AppendUvsForSide(dir, uvs); } } } } }); sw.Stop(); Console.WriteLine($"DEBUG: built chunk model [{sw.Elapsed.TotalMilliseconds:F}ms]"); float[] vtx = vertexes.ToArray(); //this is here because this takes time and I don't want it to slow down the main thread by running it in GlContext float[] nrm = normals.ToArray(); float[] uv = uvs.ToArray(); SharpCraft.Instance.RunGlContext(() => { if (_model == null) { _model = new ModelChunk(vtx, nrm, uv, Block.DefaultShader); } else { _model.OverrideData(vtx, nrm, uv); } ModelBuilding = false; }); QueuedForModelBuild = false; }