public int acceptEnergy(int offeredAmount) { if (BlockUtils.isUnbreakableBlock(world, x, y, z)) { hasFailed = true; return 0; } energyRequired = BlockUtils.computeBlockBreakEnergy(world, x, y, z); int usedAmount = MathUtils.clamp(offeredAmount, 0, Math.max(0, energyRequired - energyAccepted)); energyAccepted += usedAmount; if (energyAccepted >= energyRequired) { world.destroyBlockInWorldPartially(minerId, x, y, z, -1); hasMined = true; Block block = world.getBlock(x, y, z); int meta = world.getBlockMetadata(x, y, z); BlockEvent.BreakEvent breakEvent = new BlockEvent.BreakEvent( x, y, z, world, block, meta, CoreProxy.proxy.getBuildCraftPlayer((WorldServer) world).get()); MinecraftForge.EVENT_BUS.post(breakEvent); if (!breakEvent.isCanceled()) { List<ItemStack> stacks = BlockUtils.getItemStackFromBlock((WorldServer) world, x, y, z); if (stacks != null) { for (ItemStack s : stacks) { if (s != null) { mineStack(s); } } } world.playAuxSFXAtEntity(null, 2001, x, y, z, Block.getIdFromBlock(block) + (meta << 12)); world.setBlockToAir(x, y, z); } else { hasFailed = true; } } else { world.destroyBlockInWorldPartially( minerId, x, y, z, MathUtils.clamp((int) Math.floor(energyAccepted * 10 / energyRequired), 0, 9)); } return usedAmount; }
public int acceptEnergy(int offeredAmount) { energyRequired = BlockUtils.computeBlockBreakEnergy(world, x, y, z); int usedAmount = MathUtils.clamp(offeredAmount, 0, Math.max(0, energyRequired - energyAccepted)); energyAccepted += usedAmount; if (energyAccepted >= energyRequired) { world.destroyBlockInWorldPartially(minerId, x, y, z, -1); hasMined = true; Block block = world.getBlock(x, y, z); int meta = world.getBlockMetadata(x, y, z); /* TODO gamerforEA code replace, old code: BlockEvent.BreakEvent breakEvent = new BlockEvent.BreakEvent(x, y, z, world, block, meta, CoreProxy.proxy.getBuildCraftPlayer((WorldServer) world).get()); MinecraftForge.EVENT_BUS.post(breakEvent); if (!breakEvent.isCanceled())*/ EntityPlayer player = this.owner instanceof TileBuildCraft ? ((TileBuildCraft) this.owner).getOwnerFake() : CoreProxy.proxy.getBuildCraftPlayer((WorldServer) world).get(); if (!FakePlayerUtils.cantBreak(player, x, y, z)) // TODO gamerforEA code end { List<ItemStack> stacks = BlockUtils.getItemStackFromBlock((WorldServer) world, x, y, z); if (stacks != null) { for (ItemStack s : stacks) { if (s != null) { mineStack(s); } } } world.playAuxSFXAtEntity(null, 2001, x, y, z, Block.getIdFromBlock(block) + (meta << 12)); Utils.preDestroyBlock(world, x, y, z); world.setBlockToAir(x, y, z); } else { hasFailed = true; } } else { world.destroyBlockInWorldPartially( minerId, x, y, z, MathUtils.clamp((int) Math.floor(energyAccepted * 10 / energyRequired), 0, 9)); } return usedAmount; }
public void solve(TimeStep step, Vec2 gravity, boolean correctPositions, boolean allowSleep) { // Integrate velocities and apply damping. for (int i = 0; i < m_bodyCount; ++i) { Body b = m_bodies[i]; if (b.isStatic()) continue; // Integrate velocities. b.m_linearVelocity.x += step.dt * (gravity.x + b.m_invMass * b.m_force.x); b.m_linearVelocity.y += step.dt * (gravity.y + b.m_invMass * b.m_force.y); b.m_angularVelocity += step.dt * b.m_invI * b.m_torque; // Reset forces. b.m_force.set(0.0f, 0.0f); b.m_torque = 0.0f; // Apply damping. // ODE: dv/dt + c * v = 0 // Solution: v(t) = v0 * exp(-c * t) // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * // exp(-c * dt) // v2 = exp(-c * dt) * v1 // Taylor expansion: // v2 = (1.0f - c * dt) * v1 b.m_linearVelocity.mulLocal(MathUtils.clamp(1.0f - step.dt * b.m_linearDamping, 0.0f, 1.0f)); b.m_angularVelocity *= MathUtils.clamp(1.0f - step.dt * b.m_angularDamping, 0.0f, 1.0f); // Check for large velocities. if (Vec2.dot(b.m_linearVelocity, b.m_linearVelocity) > Settings.maxLinearVelocitySquared) { b.m_linearVelocity.normalize(); b.m_linearVelocity.mulLocal(Settings.maxLinearVelocity); } if (b.m_angularVelocity * b.m_angularVelocity > Settings.maxAngularVelocitySquared) { if (b.m_angularVelocity < 0.0f) { b.m_angularVelocity = -Settings.maxAngularVelocity; } else { b.m_angularVelocity = Settings.maxAngularVelocity; } } } ContactSolver contactSolver = new ContactSolver(step, m_contacts, m_contactCount); // Initialize velocity constraints. contactSolver.initVelocityConstraints(step); for (int i = 0; i < m_jointCount; ++i) { m_joints[i].initVelocityConstraints(step); } // Solve velocity constraints. for (int i = 0; i < step.maxIterations; ++i) { contactSolver.solveVelocityConstraints(); for (int j = 0; j < m_jointCount; ++j) { m_joints[j].solveVelocityConstraints(step); } } // Post-solve (store impulses for warm starting). contactSolver.finalizeVelocityConstraints(); // Integrate positions. for (int i = 0; i < m_bodyCount; ++i) { Body b = m_bodies[i]; if (b.isStatic()) continue; // Store positions for continuous collision. b.m_sweep.c0.set(b.m_sweep.c); b.m_sweep.a0 = b.m_sweep.a; // Integrate b.m_sweep.c.x += step.dt * b.m_linearVelocity.x; b.m_sweep.c.y += step.dt * b.m_linearVelocity.y; b.m_sweep.a += step.dt * b.m_angularVelocity; // Compute new transform b.synchronizeTransform(); // Note: shapes are synchronized later. } if (correctPositions) { // Initialize position constraints. // Contacts don't need initialization. for (int i = 0; i < m_jointCount; ++i) { m_joints[i].initPositionConstraints(); } // Iterate over constraints. for (m_positionIterationCount = 0; m_positionIterationCount < step.maxIterations; ++m_positionIterationCount) { boolean contactsOkay = contactSolver.solvePositionConstraints(Settings.contactBaumgarte); boolean jointsOkay = true; for (int i = 0; i < m_jointCount; ++i) { boolean jointOkay = m_joints[i].solvePositionConstraints(); jointsOkay = jointsOkay && jointOkay; } if (contactsOkay && jointsOkay) { break; } } } report(contactSolver.m_constraints); if (allowSleep) { float minSleepTime = Float.MAX_VALUE; final float linTolSqr = Settings.linearSleepTolerance * Settings.linearSleepTolerance; final float angTolSqr = Settings.angularSleepTolerance * Settings.angularSleepTolerance; for (int i = 0; i < m_bodyCount; ++i) { Body b = m_bodies[i]; if (b.m_invMass == 0.0f) { continue; } if ((b.m_flags & Body.e_allowSleepFlag) == 0) { b.m_sleepTime = 0.0f; minSleepTime = 0.0f; } if ((b.m_flags & Body.e_allowSleepFlag) == 0 || b.m_angularVelocity * b.m_angularVelocity > angTolSqr || Vec2.dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr) { b.m_sleepTime = 0.0f; minSleepTime = 0.0f; } else { b.m_sleepTime += step.dt; minSleepTime = Math.min(minSleepTime, b.m_sleepTime); } } if (minSleepTime >= Settings.timeToSleep) { for (int i = 0; i < m_bodyCount; ++i) { Body b = m_bodies[i]; b.m_flags |= Body.e_sleepFlag; b.m_linearVelocity = new Vec2(0.0f, 0.0f); b.m_angularVelocity = 0.0f; } } } }
// From Muzei, Copyright 2014 Google Inc. public static Drawable makeScrimDrawable(int baseColor, int numStops, int gravity) { numStops = Math.max(numStops, 2); PaintDrawable paintDrawable = new PaintDrawable(); paintDrawable.setShape(new RectShape()); final int[] stopColors = new int[numStops]; int red = Color.red(baseColor); int green = Color.green(baseColor); int blue = Color.blue(baseColor); int alpha = Color.alpha(baseColor); for (int i = 0; i < numStops; i++) { float x = i * 1f / (numStops - 1); float opacity = MathUtils.clamp((float) Math.pow(x, 3), 0, 1); stopColors[i] = Color.argb((int) (alpha * opacity), red, green, blue); } final float x0, x1, y0, y1; switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) { case Gravity.LEFT: x0 = 1; x1 = 0; break; case Gravity.RIGHT: x0 = 0; x1 = 1; break; default: x0 = 0; x1 = 0; break; } switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) { case Gravity.TOP: y0 = 1; y1 = 0; break; case Gravity.BOTTOM: y0 = 0; y1 = 1; break; default: y0 = 0; y1 = 0; break; } paintDrawable.setShaderFactory( new ShapeDrawable.ShaderFactory() { @Override public Shader resize(int width, int height) { return new LinearGradient( width * x0, height * y0, width * x1, height * y1, stopColors, null, Shader.TileMode.CLAMP); } }); paintDrawable.setAlpha(Math.round(0.4f * 255)); return paintDrawable; }