public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { if (ParticleProperties != null && ParticleProperties.Length > 0) { int rnd = GameMath.MurmurHash3Mod(pos.X, pos.Y, pos.Z, 4); Vec3f[] poses = candleWickPositionsByRot[rnd]; for (int i = 0; i < ParticleProperties.Length; i++) { AdvancedParticleProperties bps = ParticleProperties[i]; bps.WindAffectednesAtPos = windAffectednessAtPos; for (int j = 0; j < QuantityCandles; j++) { Vec3f dp = poses[j]; bps.basePos.X = pos.X + dp.X; bps.basePos.Y = pos.Y + dp.Y; bps.basePos.Z = pos.Z + dp.Z; manager.Spawn(bps); } } } }
public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { if (IsExtinct) { base.OnAsyncClientParticleTick(manager, pos, windAffectednessAtPos, secondsTicking); return; } BlockEntityKiln bef = manager.BlockAccess.GetBlockEntity(pos) as BlockEntityKiln; if (bef != null && bef.CurrentModel == EnumKilnModel.Smelting) { for (int i = 0; i < ringParticles.Length; i++) { AdvancedParticleProperties bps = ringParticles[i]; bps.WindAffectednesAtPos = windAffectednessAtPos; bps.basePos.X = pos.X + basePos[i].X; bps.basePos.Y = pos.Y + basePos[i].Y; bps.basePos.Z = pos.Z + basePos[i].Z; manager.Spawn(bps); } return; } base.OnAsyncClientParticleTick(manager, pos, windAffectednessAtPos, secondsTicking); }
public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { if (api.World.Rand.NextDouble() > particleQuantity) { return; } AdvancedParticleProperties bps = ParticleProperties[0]; bps.basePos.X = pos.X; bps.basePos.Y = pos.Y; bps.basePos.Z = pos.Z; bps.Velocity[0].avg = (float)PushVector.X * 500; bps.Velocity[1].avg = (float)PushVector.Y * 500; bps.Velocity[2].avg = (float)PushVector.Z * 500; bps.GravityEffect.avg = 0.5f; bps.HsvaColor[3].avg = 180 * Math.Min(1, secondsTicking / 7f); bps.Quantity.avg = 1; bps.PosOffset[1].avg = 2 / 16f; bps.PosOffset[1].var = LiquidLevel / 8f * 0.75f; bps.SwimOnLiquid = true; manager.Spawn(bps); }
public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { if (ParticleProperties != null && ParticleProperties.Length > 0) { for (int i = 0; i < 4; i++) { if (api.World.Rand.NextDouble() > particleQuantity) { continue; } BlockFacing facing = BlockFacing.HORIZONTALS[i]; Block block = manager.BlockAccess.GetBlock(pos.X + facing.Normali.X, pos.Y, pos.Z + facing.Normali.Z); if (block.IsLiquid() || block.SideSolid[facing.Opposite.Index]) { continue; } AdvancedParticleProperties bps = ParticleProperties[i]; bps.basePos.X = pos.X + TopMiddlePos.X; bps.basePos.Y = pos.Y; bps.basePos.Z = pos.Z + TopMiddlePos.Z; bps.WindAffectednes = windAffectednessAtPos * 0.25f; bps.HsvaColor[3].avg = 180 * Math.Min(1, secondsTicking / 7f); bps.Quantity.avg = 1; bps.Velocity[1].avg = -0.4f; manager.Spawn(bps); } } }
public override bool OnTryIgniteBlock(IEntityAgent byEntity, BlockPos pos, float secondsIgniting, ref EnumHandling handling) { BlockEntityForge bea = byEntity.World.BlockAccessor.GetBlockEntity(pos) as BlockEntityForge; handling = EnumHandling.PreventDefault; if (bea == null || !bea.CanIgnite) { return(false); } if (secondsIgniting > 0.25f && (int)(30 * secondsIgniting) % 9 == 1) { Random rand = byEntity.World.Rand; Vec3d dpos = new Vec3d(pos.X + 2 / 8f + 4 / 8f * rand.NextDouble(), pos.Y + 7 / 8f, pos.Z + 2 / 8f + 4 / 8f * rand.NextDouble()); Block blockFire = byEntity.World.GetBlock(new AssetLocation("fire")); AdvancedParticleProperties props = blockFire.ParticleProperties[blockFire.ParticleProperties.Length - 1]; props.basePos = dpos; props.Quantity.avg = 1; IPlayer byPlayer = null; if (byEntity is IEntityPlayer) { byPlayer = byEntity.World.PlayerByUid(((IEntityPlayer)byEntity).PlayerUID); } byEntity.World.SpawnParticles(props, byPlayer); props.Quantity.avg = 0; } return(secondsIgniting < 2f); }
public override void OnClientGameTick(IWorldAccessor world, BlockPos pos, float secondsTicking) { if (ParticleProperties != null && ParticleProperties.Length > 0) { for (int i = 0; i < 4; i++) { if (world.Rand.NextDouble() > particleQuantity) { continue; } BlockFacing facing = BlockFacing.HORIZONTALS[i]; Block block = world.BlockAccessor.GetBlock(pos.X + facing.Normali.X, pos.Y, pos.Z + facing.Normali.Z); if (block.IsLiquid() || block.SideSolid[facing.GetOpposite().Index]) { continue; } AdvancedParticleProperties bps = ParticleProperties[i]; bps.basePos.X = pos.X + TopMiddlePos.X; bps.basePos.Y = pos.Y; bps.basePos.Z = pos.Z + TopMiddlePos.Z; bps.HsvaColor[3].avg = 180 * Math.Min(1, secondsTicking / 7f); bps.Quantity.avg = 1; bps.Velocity[1].avg = -0.4f; world.SpawnParticles(bps); } } }
private void OnClientTick(float dt) { if (!lit) { return; } BlockPos pos = new BlockPos(); foreach (var val in smokeLocations) { if (Api.World.Rand.NextDouble() < 0.2f && Block.ParticleProperties.Length > 0) { pos.Set(val.Key.X, val.Value + 1, val.Key.Z); Block upblock = Api.World.BlockAccessor.GetBlock(pos); AdvancedParticleProperties particles = Block.ParticleProperties[0]; particles.basePos = BlockEntityFire.RandomBlockPos(Api.World.BlockAccessor, pos, upblock, BlockFacing.UP); particles.Quantity.avg = 1; Api.World.SpawnParticles(particles); particles.Quantity.avg = 0; } } }
private void OnTick(float dt) { if (Api.Side == EnumAppSide.Server) { remainingBurnDuration -= dt; OnFireTick?.Invoke(dt); float spreadChance = (TimePassed - 2.5f) / 450f; if (((ICoreServerAPI)Api).Server.Config.AllowFireSpread && spreadChance > Api.World.Rand.NextDouble()) { TrySpreadFireAllDirs(); } } if (Api.Side == EnumAppSide.Client) { int index = Math.Min(fireBlock.ParticleProperties.Length - 1, Api.World.Rand.Next(fireBlock.ParticleProperties.Length + 1)); AdvancedParticleProperties particles = fireBlock.ParticleProperties[index]; particles.basePos = RandomBlockPos(Api.World.BlockAccessor, FuelPos, fuelBlock, particleFacing); particles.Quantity.avg = 0.75f; particles.TerrainCollision = false; Api.World.SpawnParticles(particles); particles.Quantity.avg = 0; } }
public override void OnClientGameTick(IWorldAccessor world, BlockPos pos, float secondsTicking) { if (world.Rand.NextDouble() > particleQuantity) { return; } AdvancedParticleProperties bps = ParticleProperties[0]; bps.basePos.X = pos.X; bps.basePos.Y = pos.Y; bps.basePos.Z = pos.Z; bps.Velocity[0].avg = (float)PushVector.X * 250; bps.Velocity[1].avg = (float)PushVector.Y * 250; bps.Velocity[2].avg = (float)PushVector.Z * 250; bps.GravityEffect.avg = 0.5f; bps.HsvaColor[3].avg = 180 * Math.Min(1, secondsTicking / 7f); bps.Quantity.avg = 1; bps.PosOffset[1].avg = 2 / 16f; bps.PosOffset[1].var = LiquidLevel / 8f * 0.75f; bps.SwimOnLiquid = true; world.SpawnParticles(bps); }
public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, ref EnumHandling handling) { if (blockSel == null) { return(false); } IPlayer byPlayer = (byEntity as EntityPlayer)?.Player; if (!byEntity.World.Claims.TryAccess(byPlayer, blockSel.Position, EnumBlockAccessFlags.BuildOrBreak)) { return(false); } Block block = byEntity.World.BlockAccessor.GetBlock(blockSel.Position); EnumHandling igniteHandled = EnumHandling.PassThrough; bool handledResult = block.OnTryIgniteBlock(byEntity, blockSel.Position, secondsUsed, ref igniteHandled); if (igniteHandled == EnumHandling.PassThrough && !byEntity.Controls.Sneak) { return(false); } handling = EnumHandling.PreventDefault; if (byEntity.World is IClientWorldAccessor) { ModelTransform tf = new ModelTransform(); tf.EnsureDefaultValues(); tf.Translation.Set(0, -Math.Min(1.1f / 3, secondsUsed * 4 / 3f), -Math.Min(1.1f, secondsUsed * 4)); tf.Rotation.X = -Math.Min(85, secondsUsed * 90 * 4f); byEntity.Controls.UsingHeldItemTransformBefore = tf; if (igniteHandled == EnumHandling.PassThrough && secondsUsed > 0.25f && (int)(30 * secondsUsed) % 2 == 1) { Vec3d pos = BlockEntityFire.RandomBlockPos(byEntity.World.BlockAccessor, blockSel.Position, block, blockSel.Face); Block blockFire = byEntity.World.GetBlock(new AssetLocation("fire")); AdvancedParticleProperties props = blockFire.ParticleProperties[blockFire.ParticleProperties.Length - 1]; props.basePos = pos; props.Quantity.avg = 1; byEntity.World.SpawnParticles(props, byPlayer); props.Quantity.avg = 0; } } return(igniteHandled != EnumHandling.PassThrough ? handledResult : secondsUsed <= 3.1); }
private void onClientTick50ms(float dt) { if (processComplete || !structureComplete) { return; } receivesHeatSmooth = GameMath.Clamp(receivesHeatSmooth + (receivesHeat ? dt / 10 : -dt / 3), 0, 1); if (receivesHeatSmooth == 0) { return; } Random rnd = Api.World.Rand; for (int i = 0; i < Entity.FireParticleProps.Length; i++) { int index = Math.Min(Entity.FireParticleProps.Length - 1, Api.World.Rand.Next(Entity.FireParticleProps.Length + 1)); AdvancedParticleProperties particles = Entity.FireParticleProps[index]; for (int j = 0; j < particlePositions.Length; j++) { BlockPos pos = particlePositions[j]; if (j >= 6) { particles = smokeParticles; particles.Quantity.avg = 0.2f; particles.basePos.Set(pos.X + 0.5, pos.Y + 0.75, pos.Z + 0.5); particles.Velocity[1].avg = (float)(0.3 + 0.3 * rnd.NextDouble()); particles.PosOffset[1].var = 0.2f; particles.Velocity[0].avg = (float)(rnd.NextDouble() - 0.5) / 4; particles.Velocity[2].avg = (float)(rnd.NextDouble() - 0.5) / 4; } else { particles.Quantity.avg = GameMath.Sqrt(0.5f * (index == 0 ? 0.5f : (index == 1 ? 5 : 0.6f))) / 2f; particles.basePos.Set(pos.X + 0.5, pos.Y + 0.5, pos.Z + 0.5); particles.Velocity[1].avg = (float)(0.5 + 0.5 * rnd.NextDouble()); particles.PosOffset[1].var = 1; particles.Velocity[0].avg = (float)(rnd.NextDouble() - 0.5) / 2; particles.Velocity[2].avg = (float)(rnd.NextDouble() - 0.5) / 2; } particles.PosOffset[0].var = 0.49f; particles.PosOffset[2].var = 0.49f; Api.World.SpawnParticles(particles); } } }
private void OnTick(float dt) { if (api.Side == EnumAppSide.Server) { remainingBurnDuration -= dt; if (remainingBurnDuration <= 0) { BlockPos fuelPos = pos.AddCopy(fromFacing.GetOpposite()); Block fuelBlock = api.World.BlockAccessor.GetBlock(fuelPos); if (fuelBlock.CombustibleProps != null && fuelBlock.CombustibleProps.BurnDuration > 0) { api.World.BlockAccessor.SetBlock(fireBlock.BlockId, fuelPos); BlockEntityFire befire = api.World.BlockAccessor.GetBlockEntity(pos.AddCopy(fromFacing.GetOpposite())) as BlockEntityFire; if (befire != null) { befire.Init(fromFacing); } } else { } api.World.BlockAccessor.SetBlock(0, pos); api.World.BlockAccessor.RemoveBlockEntity(pos); // Sometimes block entities don't get removed properly o.O return; } float spreadChance = (TimePassed - 2.5f) / 500f; if (spreadChance > api.World.Rand.NextDouble()) { TrySpreadFire(); } } if (api.Side == EnumAppSide.Client) { int index = Math.Min(fireBlock.ParticleProperties.Length - 1, api.World.Rand.Next(fireBlock.ParticleProperties.Length + 1)); AdvancedParticleProperties particles = fireBlock.ParticleProperties[index]; particles.basePos = RandomBlockPos(api.World.BlockAccessor, pos.AddCopy(fromFacing.GetOpposite()), neibBlock, fromFacing); particles.Quantity.avg = 0.75f; particles.TerrainCollision = false; api.World.SpawnParticles(particles); particles.Quantity.avg = 0; } }
private void OnTick(float dt) { if (api.Side == EnumAppSide.Server) { remainingBurnDuration -= dt; if (remainingBurnDuration <= 0) { BlockPos fuelPos = pos.AddCopy(fromFacing.GetOpposite()); Block fuelBlock = api.World.BlockAccessor.GetBlock(fuelPos); if (canBurn(fuelBlock, fuelPos)) { TrySpreadTo(fuelPos, fromFacing); } api.World.BlockAccessor.SetBlock(0, pos); api.World.BlockAccessor.RemoveBlockEntity(pos); // Sometimes block entities don't get removed properly o.O api.World.BlockAccessor.TriggerNeighbourBlockUpdate(pos); return; } float spreadChance = (TimePassed - 2.5f) / 450f; if (((ICoreServerAPI)api).Server.Config.AllowFireSpread && spreadChance > api.World.Rand.NextDouble()) { TrySpreadFire(); } } if (api.Side == EnumAppSide.Client) { int index = Math.Min(fireBlock.ParticleProperties.Length - 1, api.World.Rand.Next(fireBlock.ParticleProperties.Length + 1)); AdvancedParticleProperties particles = fireBlock.ParticleProperties[index]; particles.basePos = RandomBlockPos(api.World.BlockAccessor, pos.AddCopy(fromFacing.GetOpposite()), neibBlock, fromFacing); particles.Quantity.avg = 0.75f; particles.TerrainCollision = false; api.World.SpawnParticles(particles); particles.Quantity.avg = 0; } }
public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { if (ParticleProperties != null && ParticleProperties.Length > 0) { for (int i = 0; i < 4; i++) { if (api.World.Rand.NextDouble() > particleQuantity) { continue; } BlockFacing facing = BlockFacing.HORIZONTALS[i]; Block block = manager.BlockAccess.GetBlock(pos.X + facing.Normali.X, pos.Y, pos.Z + facing.Normali.Z); if (block.IsLiquid() || block.SideSolid[facing.Opposite.Index]) { continue; } AdvancedParticleProperties bps = ParticleProperties[i]; bps.basePos.X = pos.X + TopMiddlePos.X; bps.basePos.Y = pos.Y; bps.basePos.Z = pos.Z + TopMiddlePos.Z; bps.WindAffectednes = windAffectednessAtPos * 0.25f; bps.HsvaColor[3].avg = 180 * Math.Min(1, secondsTicking / 7f); bps.Quantity.avg = 1; bps.Velocity[1].avg = -0.4f; bps.Velocity[0].avg = API.Config.GlobalConstants.CurrentWindSpeedClient.X * windAffectednessAtPos; bps.Velocity[2].avg = API.Config.GlobalConstants.CurrentWindSpeedClient.Z * windAffectednessAtPos; bps.Size.avg = 0.05f; bps.Size.var = 0f; bps.SizeEvolve = EvolvingNatFloat.create(EnumTransformFunction.LINEAR, 0.8f); manager.Spawn(bps); } } }
public override EnumIgniteState OnTryIgniteBlock(EntityAgent byEntity, BlockPos pos, float secondsIgniting) { BlockEntityCoalPile bea = byEntity.World.BlockAccessor.GetBlockEntity(pos) as BlockEntityCoalPile; if (bea == null || !bea.CanIgnite) { return(EnumIgniteState.NotIgnitablePreventDefault); } if (secondsIgniting > 0.25f && (int)(30 * secondsIgniting) % 9 == 1) { Random rand = byEntity.World.Rand; Vec3d dpos = new Vec3d(pos.X + 2 / 8f + 4 / 8f * rand.NextDouble(), pos.Y + 7 / 8f, pos.Z + 2 / 8f + 4 / 8f * rand.NextDouble()); Block blockFire = byEntity.World.GetBlock(new AssetLocation("fire")); AdvancedParticleProperties props = blockFire.ParticleProperties[blockFire.ParticleProperties.Length - 1]; props.basePos = dpos; props.Quantity.avg = 1; IPlayer byPlayer = null; if (byEntity is EntityPlayer) { byPlayer = byEntity.World.PlayerByUid(((EntityPlayer)byEntity).PlayerUID); } byEntity.World.SpawnParticles(props, byPlayer); props.Quantity.avg = 0; } if (secondsIgniting >= 1.5f) { return(EnumIgniteState.IgniteNow); } return(EnumIgniteState.Ignitable); }
private void OnGameTick(float dt) { IClientWorldAccessor clientWorld = (IClientWorldAccessor)Api.World; if (!clientWorld.Player.Entity.Pos.InRangeOf(Pos, 128 * 128)) { return; } if (block == null || block.ParticleProperties == null) { return; } for (int i = 0; i < block.ParticleProperties.Length; i++) { AdvancedParticleProperties bps = block.ParticleProperties[i]; bps.basePos.X = Pos.X + block.TopMiddlePos.X; bps.basePos.Y = Pos.Y + block.TopMiddlePos.Y; bps.basePos.Z = Pos.Z + block.TopMiddlePos.Z; Api.World.SpawnParticles(bps); } }
public virtual void RenderParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking, AdvancedParticleProperties[] particles) { if (this.fuelBurnTime < 3) { return; } int logsCount = FuelSlot.StackSize; bool fireFull = logsCount > 3; //fireFull means it's a fire with 2 rows of logs (between 4 and 6 logs) - flames will start higher double[] x = new double[4]; float[] z = new float[4]; for (int i = 0; i < particles.Length; i++) { //reduced number of bright yellow flames - and reduces as the fuel burns if (i >= 12 && prng.Next(0, 90) > this.fuelBurnTime) { continue; } //limit orange flames when fuel is almost burned if (i >= 8 && i < 12 && prng.Next(0, 12) > this.fuelBurnTime) { continue; } //also randomise red flames if (i >= 4 && i < 4 && prng.Next(0, 6) == 0) { continue; } //adjust flames to the number of logs, if less than 3 logs if (i >= 4 && logsCount < 3) { bool rotated = this.rotation >= 180; if (!rotated && z[i % 2] > logsCount * 0.2f + 0.14f) { continue; } if (rotated && z[i % 2] < (3 - logsCount) * 0.2f + 0.14f) { continue; } } AdvancedParticleProperties bps = particles[i]; bps.WindAffectednesAtPos = 0f; bps.basePos.X = pos.X; bps.basePos.Y = pos.Y + (fireFull ? 3 / 32f : 1 / 32f); bps.basePos.Z = pos.Z; //i >= 4 is flames; i < 4 is smoke if (i >= 4) { bool rotate = this.rotation % 180 > 0; if (fireFull) { rotate = !rotate; } bps.basePos.Z += rotate ? x[i % 2] : z[i % 2]; bps.basePos.X += rotate ? z[i % 2] : x[i % 2]; bps.basePos.Y += (fireFull ? 4 : 3) / 32f; switch (this.rotation) { case 0: bps.basePos.X -= fireFull ? 0.08f : 0.12f; break; case 180: bps.basePos.X += fireFull ? 0.08f : 0.12f; break; case 90: bps.basePos.Z += fireFull ? 0.08f : 0.12f; break; default: bps.basePos.Z -= fireFull ? 0.08f : 0.12f; break; } } else //set up flame positions with RNG (this way all three flame evolution particles will be in approx. same position) { x[i] = prng.NextDouble() * 0.4f + 0.33f; // the multiplier and offset gets the flame position aligned with the top surface of the logs z[i] = 0.26f + prng.Next(0, 3) * 0.2f + (float)prng.NextDouble() * 0.08f; } manager.Spawn(bps); } }
public override void DoRender3DOpaque(float dt, bool isShadowPass) { IRenderAPI rapi = capi.Render; // the value 22 is just trial&error, should probably be something proportial to the // 13ms game ticks (which is the physics frame rate) lerpedPos.X += (entity.Pos.X - lerpedPos.X) * 22 * dt; lerpedPos.Y += (entity.Pos.Y - lerpedPos.Y) * 22 * dt; lerpedPos.Z += (entity.Pos.Z - lerpedPos.Z) * 22 * dt; ItemRenderInfo renderInfo = rapi.GetItemStackRenderInfo(inslot, EnumItemRenderTarget.Ground); if (renderInfo.ModelRef == null) { return; } inslot.Itemstack.Collectible.OnBeforeRender(capi, inslot.Itemstack, EnumItemRenderTarget.Ground, ref renderInfo); IStandardShaderProgram prog = null; LoadModelMatrix(renderInfo, isShadowPass, dt); if (isShadowPass) { rapi.CurrentActiveShader.BindTexture2D("tex2d", renderInfo.TextureId, 0); float[] mvpMat = Mat4f.Mul(ModelMat, capi.Render.CurrentModelviewMatrix, ModelMat); Mat4f.Mul(mvpMat, capi.Render.CurrentProjectionMatrix, mvpMat); capi.Render.CurrentActiveShader.UniformMatrix("mvpMatrix", mvpMat); capi.Render.CurrentActiveShader.Uniform("origin", new Vec3f()); } else { prog = rapi.StandardShader; prog.Use(); prog.Tex2D = renderInfo.TextureId; prog.RgbaTint = ColorUtil.WhiteArgbVec; prog.DontWarpVertices = 0; prog.NormalShaded = 1; if (entity.Swimming) { prog.AddRenderFlags = (entityitem.Itemstack.Collectible.MaterialDensity > 1000 ? 0 : 1) << 12; prog.WaterWaveCounter = capi.Render.ShaderUniforms.WaterWaveCounter; } else { prog.AddRenderFlags = 0; } prog.OverlayOpacity = renderInfo.OverlayOpacity; if (renderInfo.OverlayTexture != null && renderInfo.OverlayOpacity > 0) { prog.Tex2dOverlay2D = renderInfo.OverlayTexture.TextureId; prog.OverlayTextureSize = new Vec2f(renderInfo.OverlayTexture.Width, renderInfo.OverlayTexture.Height); prog.BaseTextureSize = new Vec2f(renderInfo.TextureSize.Width, renderInfo.TextureSize.Height); TextureAtlasPosition texPos = rapi.GetTextureAtlasPosition(entityitem.Itemstack); prog.BaseUvOrigin = new Vec2f(texPos.x1, texPos.y1); } BlockPos pos = entityitem.Pos.AsBlockPos; Vec4f lightrgbs = capi.World.BlockAccessor.GetLightRGBs(pos.X, pos.Y, pos.Z); int temp = (int)entityitem.Itemstack.Collectible.GetTemperature(capi.World, entityitem.Itemstack); float[] glowColor = ColorUtil.GetIncandescenceColorAsColor4f(temp); int extraGlow = GameMath.Clamp((temp - 550) / 2, 0, 255); glowRgb.R = glowColor[0]; glowRgb.G = glowColor[1]; glowRgb.B = glowColor[2]; glowRgb.A = extraGlow / 255f; prog.ExtraGlow = extraGlow; prog.RgbaAmbientIn = rapi.AmbientColor; prog.RgbaLightIn = lightrgbs; prog.RgbaGlowIn = glowRgb; prog.RgbaFogIn = rapi.FogColor; prog.FogMinIn = rapi.FogMin; prog.FogDensityIn = rapi.FogDensity; prog.ExtraGodray = 0; prog.NormalShaded = renderInfo.NormalShaded ? 1 : 0; prog.ProjectionMatrix = rapi.CurrentProjectionMatrix; prog.ViewMatrix = rapi.CameraMatrixOriginf; prog.ModelMatrix = ModelMat; ItemStack stack = entityitem.Itemstack; AdvancedParticleProperties[] ParticleProperties = stack.Block?.ParticleProperties; if (stack.Block != null && !capi.IsGamePaused) { Mat4f.MulWithVec4(ModelMat, new Vec4f(stack.Block.TopMiddlePos.X, stack.Block.TopMiddlePos.Y - 0.4f, stack.Block.TopMiddlePos.Z - 0.5f, 0), particleOutTransform); // No idea why the -0.5f and -0.4f accum += dt; if (ParticleProperties != null && ParticleProperties.Length > 0 && accum > 0.025f) { accum = accum % 0.025f; for (int i = 0; i < ParticleProperties.Length; i++) { AdvancedParticleProperties bps = ParticleProperties[i]; bps.basePos.X = particleOutTransform.X + entity.Pos.X; bps.basePos.Y = particleOutTransform.Y + entity.Pos.Y; bps.basePos.Z = particleOutTransform.Z + entity.Pos.Z; entityitem.World.SpawnParticles(bps); } } } } if (!renderInfo.CullFaces) { rapi.GlDisableCullFace(); } rapi.RenderMesh(renderInfo.ModelRef); if (!renderInfo.CullFaces) { rapi.GlEnableCullFace(); } if (!isShadowPass) { prog.Stop(); } }
private void InitializeParticles() { particles = new AdvancedParticleProperties[16]; basePos = new Vec3f[particles.Length]; Cuboidf[] spawnBoxes = new Cuboidf[] { new Cuboidf(x1: 0.125f, y1: 0, z1: 0.125f, x2: 0.3125f, y2: 0.5f, z2: 0.875f), new Cuboidf(x1: 0.7125f, y1: 0, z1: 0.125f, x2: 0.875f, y2: 0.5f, z2: 0.875f), new Cuboidf(x1: 0.125f, y1: 0, z1: 0.125f, x2: 0.875f, y2: 0.5f, z2: 0.3125f), new Cuboidf(x1: 0.125f, y1: 0, z1: 0.7125f, x2: 0.875f, y2: 0.5f, z2: 0.875f) }; // This is smoke particles - similar to the Firepit for (int j = 0; j < 4; j++) { AdvancedParticleProperties props = ParticleProperties[0].Clone(); Cuboidf box = spawnBoxes[j]; basePos[j] = new Vec3f(0, 0, 0); props.PosOffset[0].avg = box.MidX; props.PosOffset[0].var = box.Width / 2; props.PosOffset[1].avg = 0.3f; props.PosOffset[1].var = 0.05f; props.PosOffset[2].avg = box.MidZ; props.PosOffset[2].var = box.Length / 2; props.Quantity.avg = 0.5f; props.Quantity.var = 0.2f; props.LifeLength.avg = 0.8f; particles[j] = props; } // The rest are flame particles: the spawn pos will be precisely controlled by spawning code in BEClayOven // This is the dark orange at the base of a flame for (int j = 4; j < 8; j++) { AdvancedParticleProperties props = ParticleProperties[1].Clone(); props.PosOffset[1].avg = 0.06f; props.PosOffset[1].var = 0.02f; props.Quantity.avg = 0.5f; props.Quantity.var = 0.2f; props.LifeLength.avg = 0.3f; props.VertexFlags = 128; particles[j] = props; } // This is the bright orange in the middle of a flame for (int j = 8; j < 12; j++) { AdvancedParticleProperties props = ParticleProperties[2].Clone(); props.PosOffset[1].avg = 0.09f; props.PosOffset[1].var = 0.02f; props.Quantity.avg = 0.5f; props.Quantity.var = 0.2f; props.LifeLength.avg = 0.18f; props.VertexFlags = 192; particles[j] = props; } // This is the bright yellow at the top of a flame for (int j = 12; j < 16; j++) { AdvancedParticleProperties props = ParticleProperties[3].Clone(); props.PosOffset[1].avg = 0.12f; props.PosOffset[1].var = 0.03f; props.Quantity.avg = 0.2f; props.Quantity.var = 0.1f; props.LifeLength.avg = 0.12f; props.VertexFlags = 255; particles[j] = props; } }
protected void RenderHeldItem(float dt, bool isShadowPass, bool right) { IRenderAPI rapi = capi.Render; ItemSlot slot = right ? eagent?.RightHandItemSlot : eagent?.LeftHandItemSlot; ItemStack stack = slot?.Itemstack; AttachmentPointAndPose apap = entity.AnimManager.Animator.GetAttachmentPointPose(right ? "RightHand" : "LeftHand"); if (apap == null || stack == null) { return; } AttachmentPoint ap = apap.AttachPoint; ItemRenderInfo renderInfo = rapi.GetItemStackRenderInfo(slot, right ? EnumItemRenderTarget.HandTp : EnumItemRenderTarget.HandTpOff); IStandardShaderProgram prog = null; if (renderInfo?.Transform == null) { return; // Happens with unknown items/blocks } ItemModelMat .Set(ModelMat) .Mul(apap.AnimModelMatrix) .Translate(renderInfo.Transform.Origin.X, renderInfo.Transform.Origin.Y, renderInfo.Transform.Origin.Z) .Scale(renderInfo.Transform.ScaleXYZ.X, renderInfo.Transform.ScaleXYZ.Y, renderInfo.Transform.ScaleXYZ.Z) .Translate(ap.PosX / 16f + renderInfo.Transform.Translation.X, ap.PosY / 16f + renderInfo.Transform.Translation.Y, ap.PosZ / 16f + renderInfo.Transform.Translation.Z) .RotateX((float)(ap.RotationX + renderInfo.Transform.Rotation.X) * GameMath.DEG2RAD) .RotateY((float)(ap.RotationY + renderInfo.Transform.Rotation.Y) * GameMath.DEG2RAD) .RotateZ((float)(ap.RotationZ + renderInfo.Transform.Rotation.Z) * GameMath.DEG2RAD) .Translate(-(renderInfo.Transform.Origin.X), -(renderInfo.Transform.Origin.Y), -(renderInfo.Transform.Origin.Z)) ; if (isShadowPass) { rapi.CurrentActiveShader.BindTexture2D("tex2d", renderInfo.TextureId, 0); float[] mvpMat = Mat4f.Mul(ItemModelMat.Values, capi.Render.CurrentModelviewMatrix, ItemModelMat.Values); Mat4f.Mul(mvpMat, capi.Render.CurrentProjectionMatrix, mvpMat); capi.Render.CurrentActiveShader.UniformMatrix("mvpMatrix", mvpMat); capi.Render.CurrentActiveShader.Uniform("origin", new Vec3f()); } else { prog = rapi.StandardShader; prog.Use(); prog.DontWarpVertices = 0; prog.AddRenderFlags = 0; prog.NormalShaded = 1; prog.Tex2D = renderInfo.TextureId; prog.RgbaTint = ColorUtil.WhiteArgbVec; prog.AlphaTest = renderInfo.AlphaTest; prog.DamageEffect = renderInfo.DamageEffect; prog.OverlayOpacity = renderInfo.OverlayOpacity; if (renderInfo.OverlayTexture != null && renderInfo.OverlayOpacity > 0) { prog.Tex2dOverlay2D = renderInfo.OverlayTexture.TextureId; prog.OverlayTextureSize = new Vec2f(renderInfo.OverlayTexture.Width, renderInfo.OverlayTexture.Height); prog.BaseTextureSize = new Vec2f(renderInfo.TextureSize.Width, renderInfo.TextureSize.Height); TextureAtlasPosition texPos = rapi.GetTextureAtlasPosition(stack); prog.BaseUvOrigin = new Vec2f(texPos.x1, texPos.y1); } int temp = (int)stack.Collectible.GetTemperature(capi.World, stack); float[] glowColor = ColorUtil.GetIncandescenceColorAsColor4f(temp); /*lightrgbs[0] += glowColor[0]; * lightrgbs[1] += glowColor[1]; * lightrgbs[2] += glowColor[2];*/ var gi = GameMath.Clamp((temp - 500) / 3, 0, 255); prog.ExtraGlow = gi; prog.RgbaAmbientIn = rapi.AmbientColor; prog.RgbaLightIn = lightrgbs; prog.RgbaGlowIn = new Vec4f(glowColor[0], glowColor[1], glowColor[2], gi / 255f); prog.RgbaFogIn = rapi.FogColor; prog.FogMinIn = rapi.FogMin; prog.FogDensityIn = rapi.FogDensity; prog.NormalShaded = renderInfo.NormalShaded ? 1 : 0; prog.ProjectionMatrix = rapi.CurrentProjectionMatrix; prog.ViewMatrix = rapi.CameraMatrixOriginf; prog.ModelMatrix = ItemModelMat.Values; } if (!renderInfo.CullFaces) { rapi.GlDisableCullFace(); } rapi.RenderMesh(renderInfo.ModelRef); if (!renderInfo.CullFaces) { rapi.GlEnableCullFace(); } if (!isShadowPass) { prog.DamageEffect = 0; } if (!isShadowPass) { prog.Stop(); AdvancedParticleProperties[] ParticleProperties = stack.Collectible?.ParticleProperties; if (stack.Collectible != null && !capi.IsGamePaused) { Vec4f pos = ItemModelMat.TransformVector(new Vec4f(stack.Collectible.TopMiddlePos.X, stack.Collectible.TopMiddlePos.Y, stack.Collectible.TopMiddlePos.Z, 1)); EntityPlayer entityPlayer = capi.World.Player.Entity; accum += dt; if (ParticleProperties != null && ParticleProperties.Length > 0 && accum > 0.025f) { accum = accum % 0.025f; for (int i = 0; i < ParticleProperties.Length; i++) { AdvancedParticleProperties bps = ParticleProperties[i]; bps.basePos.X = pos.X + entity.Pos.X + -(entity.Pos.X - entityPlayer.CameraPos.X); bps.basePos.Y = pos.Y + entity.Pos.Y + -(entity.Pos.Y - entityPlayer.CameraPos.Y); bps.basePos.Z = pos.Z + entity.Pos.Z + -(entity.Pos.Z - entityPlayer.CameraPos.Z); eagent.World.SpawnParticles(bps); } } } } }
public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel) { if (blockSel == null) { api.Event.UnregisterCallback(ObjectCacheUtil.TryGet <long>(api, "firestartersound")); return(false); } IPlayer byPlayer = (byEntity as EntityPlayer)?.Player; if (!byEntity.World.Claims.TryAccess(byPlayer, blockSel.Position, EnumBlockAccessFlags.BuildOrBreak)) { api.Event.UnregisterCallback(ObjectCacheUtil.TryGet <long>(api, "firestartersound")); return(false); } Block block = byEntity.World.BlockAccessor.GetBlock(blockSel.Position); EnumIgniteState igniteState = block.OnTryIgniteBlock(byEntity, blockSel.Position, secondsUsed); if (igniteState == EnumIgniteState.NotIgnitable || igniteState == EnumIgniteState.NotIgnitablePreventDefault) { api.Event.UnregisterCallback(ObjectCacheUtil.TryGet <long>(api, "firestartersound")); return(false); } if (byEntity.World is IClientWorldAccessor) { ModelTransform tf = new ModelTransform(); tf.EnsureDefaultValues(); float f = GameMath.Clamp(1 - 2 * secondsUsed, 0, 1); Random rand = api.World.Rand; tf.Translation.Set(f * f * f * 1.6f - 1.6f, 0, 0); tf.Rotation.Y = -Math.Min(secondsUsed * 120, 30); if (secondsUsed > 0.5f) { tf.Translation.Add((float)rand.NextDouble() * 0.1f, (float)rand.NextDouble() * 0.1f, (float)rand.NextDouble() * 0.1f); (api as ICoreClientAPI).World.SetCameraShake(0.04f); } byEntity.Controls.UsingHeldItemTransformBefore = tf; if (secondsUsed > 0.25f && (int)(30 * secondsUsed) % 2 == 1) { Vec3d pos = blockSel.Position.ToVec3d().Add(blockSel.HitPosition); Block blockFire = byEntity.World.GetBlock(new AssetLocation("fire")); AdvancedParticleProperties props = blockFire.ParticleProperties[blockFire.ParticleProperties.Length - 1].Clone(); props.basePos = pos; props.Quantity.avg = 0.3f; props.Size.avg = 0.03f; byEntity.World.SpawnParticles(props, byPlayer); props.Quantity.avg = 0; } } return(igniteState == EnumIgniteState.Ignitable); }
public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, ref EnumHandling handling) { if (blockSel == null) { return(false); } IPlayer byPlayer = (byEntity as EntityPlayer)?.Player; if (!byEntity.World.Claims.TryAccess(byPlayer, blockSel.Position, EnumBlockAccessFlags.Use)) { return(false); } Block block = byEntity.World.BlockAccessor.GetBlock(blockSel.Position); EnumIgniteState igniteState = block.OnTryIgniteBlock(byEntity, blockSel.Position, secondsUsed); if (igniteState == EnumIgniteState.NotIgnitablePreventDefault) { return(false); } handling = EnumHandling.PreventDefault; if (byEntity.World is IClientWorldAccessor) { ModelTransform tf = new ModelTransform(); tf.EnsureDefaultValues(); tf.Translation.Set(0, Math.Min(1.1f / 3, secondsUsed * 4 / 3f) / 2, -Math.Min(1.1f, secondsUsed * 4)); tf.Rotation.X = -Math.Min(30, secondsUsed * 90 * 2f); tf.Rotation.Z = -Math.Min(20, secondsUsed * 90 * 4f); byEntity.Controls.UsingHeldItemTransformBefore = tf; if (secondsUsed > 0.25f && (int)(30 * secondsUsed) % 2 == 1) { Random rand = byEntity.World.Rand; Vec3d pos = blockSel.Position.ToVec3d().Add(blockSel.HitPosition).Add(rand.NextDouble() * 0.25 - 0.125, rand.NextDouble() * 0.25 - 0.125, rand.NextDouble() * 0.25 - 0.125); Block blockFire = byEntity.World.GetBlock(new AssetLocation("fire")); AdvancedParticleProperties props = blockFire.ParticleProperties[blockFire.ParticleProperties.Length - 1].Clone(); props.basePos = pos; props.Quantity.avg = 0.5f; byEntity.World.SpawnParticles(props, byPlayer); props.Quantity.avg = 0; } } // Crappy fix to make igniting not buggy T_T if (byEntity.World.Side == EnumAppSide.Server) { return(true); } return(secondsUsed <= 3.2); }
public override void OnLoaded(ICoreAPI api) { base.OnLoaded(api); IsExtinct = LastCodePart() != "lit"; if (!IsExtinct && api.Side == EnumAppSide.Client) { ringParticles = new AdvancedParticleProperties[this.ParticleProperties.Length * 4]; basePos = new Vec3f[ringParticles.Length]; Cuboidf[] spawnBoxes = new Cuboidf[] { new Cuboidf(x1: 0.125f, y1: 0, z1: 0.125f, x2: 0.3125f, y2: 0.5f, z2: 0.875f), new Cuboidf(x1: 0.7125f, y1: 0, z1: 0.125f, x2: 0.875f, y2: 0.5f, z2: 0.875f), new Cuboidf(x1: 0.125f, y1: 0, z1: 0.125f, x2: 0.875f, y2: 0.5f, z2: 0.3125f), new Cuboidf(x1: 0.125f, y1: 0, z1: 0.7125f, x2: 0.875f, y2: 0.5f, z2: 0.875f) }; for (int i = 0; i < ParticleProperties.Length; i++) { for (int j = 0; j < 4; j++) { AdvancedParticleProperties props = ParticleProperties[i].Clone(); Cuboidf box = spawnBoxes[j]; basePos[i * 4 + j] = new Vec3f(0, 0, 0); props.PosOffset[0].avg = box.MidX; props.PosOffset[0].var = box.Width / 2; props.PosOffset[1].avg = 0.1f; props.PosOffset[1].var = 0.05f; props.PosOffset[2].avg = box.MidZ; props.PosOffset[2].var = box.Length / 2; props.Quantity.avg /= 4f; props.Quantity.var /= 4f; ringParticles[i * 4 + j] = props; } } } interactions = ObjectCacheUtil.GetOrCreate(api, "kilnInteractions-" + Stage, () => { List <ItemStack> canIgniteStacks = new List <ItemStack>(); foreach (CollectibleObject obj in api.World.Collectibles) { string firstCodePart = obj.FirstCodePart(); if (obj is Block && (obj as Block).HasBehavior <BlockBehaviorCanIgnite>() || obj is ItemFirestarter) { List <ItemStack> stacks = obj.GetHandBookStacks(api as ICoreClientAPI); if (stacks != null) { canIgniteStacks.AddRange(stacks); } } } return(new WorldInteraction[] { new WorldInteraction() { ActionLangCode = "blockhelp-kiln-open", MouseButton = EnumMouseButton.Right, ShouldApply = (WorldInteraction wi, BlockSelection blockSelection, EntitySelection entitySelection) => { return Stage == 5; } }, new WorldInteraction() { ActionLangCode = "blockhelp-kiln-ignite", MouseButton = EnumMouseButton.Right, HotKeyCode = "sneak", Itemstacks = canIgniteStacks.ToArray(), GetMatchingStacks = (wi, bs, es) => { BlockEntityKiln bef = api.World.BlockAccessor.GetBlockEntity(bs.Position) as BlockEntityKiln; if (bef?.fuelSlot != null && !bef.fuelSlot.Empty && !bef.IsBurning) { return wi.Itemstacks; } return null; } }, new WorldInteraction() { ActionLangCode = "blockhelp-kiln-refuel", MouseButton = EnumMouseButton.Right, HotKeyCode = "sneak" } }); }); }