diff --git a/server/block/ancient_debris.go b/server/block/ancient_debris.go index 32f6b2d8e..13cb7ae99 100644 --- a/server/block/ancient_debris.go +++ b/server/block/ancient_debris.go @@ -13,7 +13,7 @@ type AncientDebris struct { func (a AncientDebris) BreakInfo() BreakInfo { return newBreakInfo(30, func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierDiamond.HarvestLevel - }, pickaxeEffective, oneOf(a)) + }, pickaxeEffective, oneOf(a)).withBlastResistance(3600) } // EncodeItem ... diff --git a/server/block/anvil.go b/server/block/anvil.go index bb17b45a2..ae6e8511b 100644 --- a/server/block/anvil.go +++ b/server/block/anvil.go @@ -27,7 +27,7 @@ func (a Anvil) Model() world.BlockModel { // BreakInfo ... func (a Anvil) BreakInfo() BreakInfo { - return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(a)) + return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(a)).withBlastResistance(6000) } // Activate ... diff --git a/server/block/basalt.go b/server/block/basalt.go index fd37b0807..47e7db466 100644 --- a/server/block/basalt.go +++ b/server/block/basalt.go @@ -32,7 +32,7 @@ func (b Basalt) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world. // BreakInfo ... func (b Basalt) BreakInfo() BreakInfo { - return newBreakInfo(1.25, pickaxeHarvestable, pickaxeEffective, oneOf(b)) + return newBreakInfo(1.25, pickaxeHarvestable, pickaxeEffective, oneOf(b)).withBlastResistance(21) } // EncodeItem ... diff --git a/server/block/bedrock.go b/server/block/bedrock.go index a82a5ca63..bb10292c9 100644 --- a/server/block/bedrock.go +++ b/server/block/bedrock.go @@ -11,11 +11,6 @@ type Bedrock struct { InfiniteBurning bool } -// BreakInfo ... -func (b Bedrock) BreakInfo() BreakInfo { - return newBreakInfo(-1, neverHarvestable, nothingEffective, simpleDrops()).withBlastResistance(0.6) -} - // EncodeItem ... func (Bedrock) EncodeItem() (name string, meta int16) { return "minecraft:bedrock", 0 diff --git a/server/block/block.go b/server/block/block.go index 71a01d883..0899a2a4d 100644 --- a/server/block/block.go +++ b/server/block/block.go @@ -3,8 +3,6 @@ package block import ( "github.com/df-mc/dragonfly/server/block/cube" "github.com/df-mc/dragonfly/server/entity/damage" - "github.com/df-mc/dragonfly/server/entity/effect" - "github.com/df-mc/dragonfly/server/entity/healing" "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" @@ -245,17 +243,9 @@ func newFlammabilityInfo(encouragement, flammability int, lavaFlammable bool) Fl } } +// livingEntity ... type livingEntity interface { world.Entity - // Health returns the health of the entity. - Health() float64 - // MaxHealth returns the maximum health of the entity. - MaxHealth() float64 - // SetMaxHealth changes the maximum health of the entity to the value passed. - SetMaxHealth(v float64) - // Dead checks if the entity is considered dead. True is returned if the health of the entity is equal to or - // lower than 0. - Dead() bool // AttackImmune checks if the entity is currently immune to entity attacks. Entities typically turn // immune for half a second after being attacked. AttackImmune() bool @@ -265,33 +255,10 @@ type livingEntity interface { // Hurt returns the final amount of damage dealt to the Living entity and returns whether the Living entity // was vulnerable to the damage at all. Hurt(damage float64, src damage.Source) (n float64, vulnerable bool) - // Heal heals the entity for a given amount of health. The source passed represents the cause of the - // healing, for example healing.SourceFood if the entity healed by having a full food bar. If the health - // added to the original health exceeds the entity's max health, Heal may not add the full amount. - Heal(health float64, src healing.Source) - // KnockBack knocks the entity back with a given force and height. A source is passed which indicates the - // source of the velocity, typically the position of an attacking entity. The source is used to calculate - // the direction which the entity should be knocked back in. - KnockBack(src mgl64.Vec3, force, height float64) - // AddEffect adds an entity.Effect to the entity. If the effect is instant, it is applied to the entity - // immediately. If not, the effect is applied to the entity every time the Tick method is called. - // AddEffect will overwrite any effects present if the level of the effect is higher than the existing one, or - // if the effects' levels are equal and the new effect has a longer duration. - AddEffect(e effect.Effect) - // RemoveEffect removes any effect that might currently be active on the entity. - RemoveEffect(e effect.Type) - // Effects returns any effect currently applied to the entity. The returned effects are guaranteed not to have - // expired when returned. - Effects() []effect.Effect - // Speed returns the current speed of the living entity. The default value is different for each entity. - Speed() float64 - // SetSpeed sets the speed of an entity to a new value. - SetSpeed(float64) } +// flammableEntity ... type flammableEntity interface { - // FireProof is whether the entity is currently fireproof. - FireProof() bool // OnFireDuration returns duration of fire in ticks. OnFireDuration() time.Duration // SetOnFire sets the entity on fire for the specified duration. diff --git a/server/block/break_info.go b/server/block/break_info.go index e81bd2116..47cb8f81c 100644 --- a/server/block/break_info.go +++ b/server/block/break_info.go @@ -85,17 +85,20 @@ type BreakInfo struct { Drops func(t item.Tool, enchantments []item.Enchantment) []item.Stack // XPDrops is the range of XP a block can drop when broken. XPDrops XPDropRange - // BlastResistance ... + // BlastResistance is the blast resistance of the block, which influences the block's ability to withstand an + // explosive blast. BlastResistance float64 } -// newBreakInfo creates a BreakInfo struct with the properties passed. The XPDrops field is 0 by default. +// newBreakInfo creates a BreakInfo struct with the properties passed. The XPDrops field is 0 by default. The blast +// resistance gets set to the hardness by default, as it usually is the same. func newBreakInfo(hardness float64, harvestable func(item.Tool) bool, effective func(item.Tool) bool, drops func(item.Tool, []item.Enchantment) []item.Stack) BreakInfo { return BreakInfo{ - Hardness: hardness, - Harvestable: harvestable, - Effective: effective, - Drops: drops, + Hardness: hardness, + BlastResistance: hardness * 5, // Blast resistance is usually always just hardness multiplied by 5. + Harvestable: harvestable, + Effective: effective, + Drops: drops, } } diff --git a/server/block/bricks.go b/server/block/bricks.go index da87c0eda..3266513d7 100644 --- a/server/block/bricks.go +++ b/server/block/bricks.go @@ -8,7 +8,7 @@ type Bricks struct { // BreakInfo ... func (b Bricks) BreakInfo() BreakInfo { - return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(b)) + return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(b)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/chain.go b/server/block/chain.go index 749786526..d196460ec 100644 --- a/server/block/chain.go +++ b/server/block/chain.go @@ -41,7 +41,7 @@ func (c Chain) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.W // BreakInfo ... func (c Chain) BreakInfo() BreakInfo { - return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(c)) + return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(c)).withBlastResistance(15) } // EncodeItem ... diff --git a/server/block/coal.go b/server/block/coal.go index b1b135f85..12ac753d7 100644 --- a/server/block/coal.go +++ b/server/block/coal.go @@ -13,7 +13,7 @@ func (c Coal) FlammabilityInfo() FlammabilityInfo { // BreakInfo ... func (c Coal) BreakInfo() BreakInfo { - return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(c)) + return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(c)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/coal_ore.go b/server/block/coal_ore.go index 83c28c285..930435745 100644 --- a/server/block/coal_ore.go +++ b/server/block/coal_ore.go @@ -13,7 +13,11 @@ type CoalOre struct { // BreakInfo ... func (c CoalOre) BreakInfo() BreakInfo { - return newBreakInfo(c.Type.Hardness(), pickaxeHarvestable, pickaxeEffective, silkTouchOneOf(item.Coal{}, c)).withXPDropRange(0, 2) + i := newBreakInfo(c.Type.Hardness(), pickaxeHarvestable, pickaxeEffective, silkTouchOneOf(item.Coal{}, c)).withXPDropRange(0, 2) + if c.Type == DeepslateOre() { + i = i.withBlastResistance(9) + } + return i } // EncodeItem ... diff --git a/server/block/cobblestone.go b/server/block/cobblestone.go index e1d14bd2c..4aec07d6d 100644 --- a/server/block/cobblestone.go +++ b/server/block/cobblestone.go @@ -12,7 +12,7 @@ type Cobblestone struct { // BreakInfo ... func (c Cobblestone) BreakInfo() BreakInfo { - return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(c)) + return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(c)).withBlastResistance(30) } // RepairsStoneTools ... diff --git a/server/block/cobblestone_stairs.go b/server/block/cobblestone_stairs.go index b49fb8a09..497655498 100644 --- a/server/block/cobblestone_stairs.go +++ b/server/block/cobblestone_stairs.go @@ -45,7 +45,7 @@ func (s CobblestoneStairs) Model() world.BlockModel { // BreakInfo ... func (s CobblestoneStairs) BreakInfo() BreakInfo { - return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(s)) + return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(s)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/cocoa_bean.go b/server/block/cocoa_bean.go index f56f312f4..8ca3d4296 100644 --- a/server/block/cocoa_bean.go +++ b/server/block/cocoa_bean.go @@ -92,7 +92,7 @@ func (c CocoaBean) BreakInfo() BreakInfo { return []item.Stack{item.NewStack(c, rand.Intn(2)+2)} } return []item.Stack{item.NewStack(c, 1)} - }) + }).withBlastResistance(15) } // EncodeItem ... diff --git a/server/block/copper_ore.go b/server/block/copper_ore.go index 802bf78c0..c7e4c8e44 100644 --- a/server/block/copper_ore.go +++ b/server/block/copper_ore.go @@ -18,7 +18,7 @@ type CopperOre struct { func (c CopperOre) BreakInfo() BreakInfo { return newBreakInfo(c.Type.Hardness(), func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierStone.HarvestLevel - }, pickaxeEffective, silkTouchDrop(item.NewStack(item.RawCopper{}, rand.Intn(4)+2), item.NewStack(c, 1))) + }, pickaxeEffective, silkTouchDrop(item.NewStack(item.RawCopper{}, rand.Intn(4)+2), item.NewStack(c, 1))).withBlastResistance(9) } // EncodeItem ... diff --git a/server/block/coral_block.go b/server/block/coral_block.go index c15f5fde4..f351b0c32 100644 --- a/server/block/coral_block.go +++ b/server/block/coral_block.go @@ -48,7 +48,7 @@ func (c CoralBlock) ScheduledTick(pos cube.Pos, w *world.World, _ *rand.Rand) { // BreakInfo ... func (c CoralBlock) BreakInfo() BreakInfo { - return newBreakInfo(7, pickaxeHarvestable, pickaxeEffective, silkTouchOneOf(CoralBlock{Type: c.Type, Dead: true}, c)) + return newBreakInfo(7, pickaxeHarvestable, pickaxeEffective, silkTouchOneOf(CoralBlock{Type: c.Type, Dead: true}, c)).withBlastResistance(4.5) } // EncodeBlock ... diff --git a/server/block/diamond.go b/server/block/diamond.go index b46d84e01..cd89c09f9 100644 --- a/server/block/diamond.go +++ b/server/block/diamond.go @@ -13,7 +13,7 @@ type Diamond struct { func (d Diamond) BreakInfo() BreakInfo { return newBreakInfo(5, func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierIron.HarvestLevel - }, pickaxeEffective, oneOf(d)) + }, pickaxeEffective, oneOf(d)).withBlastResistance(30) } // PowersBeacon ... diff --git a/server/block/diamond_ore.go b/server/block/diamond_ore.go index ac8985f25..d698fb99b 100644 --- a/server/block/diamond_ore.go +++ b/server/block/diamond_ore.go @@ -15,9 +15,13 @@ type DiamondOre struct { // BreakInfo ... func (d DiamondOre) BreakInfo() BreakInfo { - return newBreakInfo(d.Type.Hardness(), func(t item.Tool) bool { + i := newBreakInfo(d.Type.Hardness(), func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierIron.HarvestLevel }, pickaxeEffective, silkTouchOneOf(item.Diamond{}, d)).withXPDropRange(3, 7) + if d.Type == DeepslateOre() { + i = i.withBlastResistance(9) + } + return i } // EncodeItem ... diff --git a/server/block/dirt.go b/server/block/dirt.go index ab1d0cf25..4e3a1cf29 100644 --- a/server/block/dirt.go +++ b/server/block/dirt.go @@ -25,7 +25,7 @@ func (d Dirt) SoilFor(block world.Block) bool { // BreakInfo ... func (d Dirt) BreakInfo() BreakInfo { - return newBreakInfo(0.5, alwaysHarvestable, shovelEffective, oneOf(d)).withBlastResistance(0.5) + return newBreakInfo(0.5, alwaysHarvestable, shovelEffective, oneOf(d)) } // Till ... diff --git a/server/block/dripstone.go b/server/block/dripstone.go index 673721f97..b3bbcb2e7 100644 --- a/server/block/dripstone.go +++ b/server/block/dripstone.go @@ -8,7 +8,7 @@ type Dripstone struct { // BreakInfo ... func (d Dripstone) BreakInfo() BreakInfo { - return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(d)) + return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(d)).withBlastResistance(5) } // EncodeItem ... diff --git a/server/block/emerald.go b/server/block/emerald.go index 0f39697e8..bebdcb9db 100644 --- a/server/block/emerald.go +++ b/server/block/emerald.go @@ -19,7 +19,7 @@ func (e Emerald) Instrument() sound.Instrument { func (e Emerald) BreakInfo() BreakInfo { return newBreakInfo(5, func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierIron.HarvestLevel - }, pickaxeEffective, oneOf(e)) + }, pickaxeEffective, oneOf(e)).withBlastResistance(30) } // PowersBeacon ... diff --git a/server/block/emerald_ore.go b/server/block/emerald_ore.go index ace930363..b43e91fca 100644 --- a/server/block/emerald_ore.go +++ b/server/block/emerald_ore.go @@ -15,9 +15,13 @@ type EmeraldOre struct { // BreakInfo ... func (e EmeraldOre) BreakInfo() BreakInfo { - return newBreakInfo(e.Type.Hardness(), func(t item.Tool) bool { + i := newBreakInfo(e.Type.Hardness(), func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierIron.HarvestLevel }, pickaxeEffective, silkTouchOneOf(item.Emerald{}, e)).withXPDropRange(3, 7) + if e.Type == DeepslateOre() { + i = i.withBlastResistance(15) + } + return i } // EncodeItem ... diff --git a/server/block/end_brick_stairs.go b/server/block/end_brick_stairs.go index a0aea5070..45478c35d 100644 --- a/server/block/end_brick_stairs.go +++ b/server/block/end_brick_stairs.go @@ -42,7 +42,7 @@ func (s EndBrickStairs) Model() world.BlockModel { // BreakInfo ... func (s EndBrickStairs) BreakInfo() BreakInfo { - return newBreakInfo(3, pickaxeHarvestable, pickaxeEffective, oneOf(s)) + return newBreakInfo(3, pickaxeHarvestable, pickaxeEffective, oneOf(s)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/end_stone.go b/server/block/end_stone.go index 254f0b454..98224ed1c 100644 --- a/server/block/end_stone.go +++ b/server/block/end_stone.go @@ -8,7 +8,7 @@ type EndStone struct { // BreakInfo ... func (e EndStone) BreakInfo() BreakInfo { - return newBreakInfo(3, pickaxeHarvestable, pickaxeEffective, oneOf(e)) + return newBreakInfo(3, pickaxeHarvestable, pickaxeEffective, oneOf(e)).withBlastResistance(45) } // EncodeItem ... diff --git a/server/block/ender_chest.go b/server/block/ender_chest.go index c6524a3b5..4b31f07d1 100644 --- a/server/block/ender_chest.go +++ b/server/block/ender_chest.go @@ -36,7 +36,7 @@ func NewEnderChest() EnderChest { // BreakInfo ... func (c EnderChest) BreakInfo() BreakInfo { - return newBreakInfo(22.5, pickaxeHarvestable, pickaxeEffective, silkTouchDrop(item.NewStack(Obsidian{}, 8), item.NewStack(NewEnderChest(), 1))) + return newBreakInfo(22.5, pickaxeHarvestable, pickaxeEffective, silkTouchDrop(item.NewStack(Obsidian{}, 8), item.NewStack(NewEnderChest(), 1))).withBlastResistance(3000) } // LightEmissionLevel ... diff --git a/server/block/explosion.go b/server/block/explosion.go index 461db15a6..b959ae3fc 100644 --- a/server/block/explosion.go +++ b/server/block/explosion.go @@ -5,14 +5,54 @@ import ( "github.com/df-mc/dragonfly/server/block/cube/trace" "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" + "github.com/df-mc/dragonfly/server/world/particle" + "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" "math" "math/rand" "time" ) +// ExplosionConfig is the configuration for an explosion. The world, position, size, sound, particle, and more can all +// be configured through this configuration. +type ExplosionConfig struct { + // World is the world in which the explosion should take place. + World *world.World + // Pos is the center position of the explosion. + Pos mgl64.Vec3 + // Radius is the radius of the explosion. + Radius float64 + // Rand is the source to use for the explosion "randomness". If set to nil, this will default to the global rand. + Rand rand.Source + // CreateFire is true if the explosion should create fire, for example, if it came from a fireball of a ghast or + // a bed in the nether. + CreateFire bool + + // Sound is the sound to play when the explosion is created. If set to nil, this will default to the sound of a + // regular explosion. + Sound world.Sound + // Particle is the particle to spawn when the explosion is created. If set to nil, this will default to the particle + // of a regular huge explosion. + Particle world.Particle +} + +// ExplodableEntity represents an entity that can be exploded. +type ExplodableEntity interface { + // Explode is called when an explosion occurs. The entity can then react to the explosion using the configuration + // and impact provided. + Explode(c ExplosionConfig, impact float64) +} + +// Explodable represents a block that can be exploded. +type Explodable interface { + // Explode is called when an explosion occurs. The block can react to the explosion using the configuration passed. + Explode(pos cube.Pos, c ExplosionConfig) +} + +// rays ... var rays = make([]mgl64.Vec3, 0, 1352) +// init ... func init() { for x := 0.0; x < 16; x++ { for y := 0.0; y < 16; y++ { @@ -26,31 +66,19 @@ func init() { } } -type ExplodableEntity interface { - Explode(c ExplosionConfig, impact float64) -} - -type Explodable interface { - Explode(pos cube.Pos, c ExplosionConfig) -} - -type ExplosionConfig struct { - World *world.World - Pos mgl64.Vec3 - Size float64 - Rand rand.Source - Fire bool - - Sound world.Sound - Particle world.Particle -} - +// Do performs the explosion as specified by the configuration. func (c ExplosionConfig) Do() { + if c.Sound == nil { + c.Sound = sound.Explosion{} + } + if c.Particle == nil { + c.Particle = particle.HugeExplosion{} + } if c.Rand == nil { c.Rand = rand.NewSource(time.Now().UnixNano()) } - r := rand.New(c.Rand) - d := c.Size * 2 + + r, d := rand.New(c.Rand), c.Radius*2 bb := cube.Box( math.Floor(c.Pos[0]-d-1), math.Ceil(c.Pos[0]+d+1), @@ -77,7 +105,7 @@ func (c ExplosionConfig) Do() { var affectedBlocks = make([]cube.Pos, 0, 32) for _, ray := range rays { pos := c.Pos - for blastForce := c.Size * (0.7 + r.Float64()*0.6); blastForce > 0.0; blastForce -= 0.225 { + for blastForce := c.Radius * (0.7 + r.Float64()*0.6); blastForce > 0.0; blastForce -= 0.225 { current := cube.PosFromVec3(pos) if r, ok := c.World.Block(current).(Breakable); ok { if blastForce -= (r.BreakInfo().BlastResistance + 0.3) * 0.3; blastForce > 0 { @@ -93,14 +121,14 @@ func (c ExplosionConfig) Do() { explodable.Explode(pos, c) } else if breakable, ok := bl.(Breakable); ok { c.World.SetBlock(pos, nil, nil) - if 1/c.Size > rand.Float64() { + if 1/c.Radius > rand.Float64() { for _, drop := range breakable.BreakInfo().Drops(item.ToolNone{}, nil) { dropItem(c.World, drop, pos.Vec3Centre()) } } } } - if c.Fire { + if c.CreateFire { for _, pos := range affectedBlocks { if rand.Intn(3) == 0 { if _, ok := c.World.Block(pos).(Air); ok { @@ -118,31 +146,35 @@ func (c ExplosionConfig) Do() { } } -// TODO +// exposure returns the exposure of a block to an entity, used to calculate the impact of an explosion. func exposure(origin mgl64.Vec3, e world.Entity) float64 { w := e.World() pos := e.Position() - bb := e.BBox().Translate(pos) - min, max := bb.Min(), bb.Max() - diff := max.Sub(min).Mul(2.0).Add(mgl64.Vec3{1, 1, 1}) + box := e.BBox().Translate(pos) + + boxMin, boxMax := box.Min(), box.Max() + diff := boxMax.Sub(boxMin).Mul(2.0).Add(mgl64.Vec3{1, 1, 1}) + double4 := 1.0 / diff[0] double5 := 1.0 / diff[1] double6 := 1.0 / diff[2] - double7 := (1.0 - math.Floor(1.0/double4)*double4) / 2.0 - double8 := (1.0 - math.Floor(1.0/double6)*double6) / 2.0 if double4 < 0.0 || double5 < 0.0 || double6 < 0.0 { return 0.0 } - integer14 := 0.0 - integer15 := 0.0 + + double7 := (1.0 - math.Floor(1.0/double4)*double4) / 2.0 + double8 := (1.0 - math.Floor(1.0/double6)*double6) / 2.0 + + var integer14, integer15 float64 for float16 := 0.0; float16 <= 1.0; float16 += double4 { for float17 := 0.0; float17 <= 1.0; float17 += double5 { for float18 := 0.0; float18 <= 1.0; float18 += double6 { dck2 := mgl64.Vec3{ - lerp(float16, min[0], max[0]) + double7, - lerp(float17, min[1], max[1]), - lerp(float18, min[2], max[2]) + double8, + lerp(float16, boxMin[0], boxMax[0]) + double7, + lerp(float17, boxMin[1], boxMax[1]), + lerp(float18, boxMin[2], boxMax[2]) + double8, } + var collides bool trace.TraverseBlocks(dck2, origin, func(pos cube.Pos) (con bool) { _, air := w.Block(pos).(Air) @@ -159,6 +191,7 @@ func exposure(origin mgl64.Vec3, e world.Entity) float64 { return integer14 / integer15 } -func lerp(v, v1, t float64) float64 { - return (1-t)*v + t*v1 +// lerp returns the linear interpolation between a and b at t. +func lerp(a, b, t float64) float64 { + return (1-t)*a + t*b } diff --git a/server/block/gilded_blackstone.go b/server/block/gilded_blackstone.go index 2611577e2..bcc5d4102 100644 --- a/server/block/gilded_blackstone.go +++ b/server/block/gilded_blackstone.go @@ -17,7 +17,7 @@ func (b GildedBlackstone) BreakInfo() BreakInfo { return []item.Stack{item.NewStack(item.GoldNugget{}, rand.Intn(4)+2)} } return []item.Stack{item.NewStack(b, 1)} - }) + }).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/gold.go b/server/block/gold.go index 85a676d7a..6e901e76a 100644 --- a/server/block/gold.go +++ b/server/block/gold.go @@ -19,7 +19,7 @@ func (g Gold) Instrument() sound.Instrument { func (g Gold) BreakInfo() BreakInfo { return newBreakInfo(5, func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierIron.HarvestLevel - }, pickaxeEffective, oneOf(g)) + }, pickaxeEffective, oneOf(g)).withBlastResistance(30) } // PowersBeacon ... diff --git a/server/block/gold_ore.go b/server/block/gold_ore.go index 7bfc72589..03a58e99e 100644 --- a/server/block/gold_ore.go +++ b/server/block/gold_ore.go @@ -15,9 +15,13 @@ type GoldOre struct { // BreakInfo ... func (g GoldOre) BreakInfo() BreakInfo { - return newBreakInfo(g.Type.Hardness(), func(t item.Tool) bool { + i := newBreakInfo(g.Type.Hardness(), func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierIron.HarvestLevel }, pickaxeEffective, silkTouchOneOf(item.RawGold{}, g)) + if g.Type == DeepslateOre() { + i = i.withBlastResistance(9) + } + return i } // EncodeItem ... diff --git a/server/block/grass.go b/server/block/grass.go index c2289ab35..54bc5a839 100644 --- a/server/block/grass.go +++ b/server/block/grass.go @@ -92,7 +92,7 @@ func (g Grass) BoneMeal(pos cube.Pos, w *world.World) bool { // BreakInfo ... func (g Grass) BreakInfo() BreakInfo { - return newBreakInfo(0.6, alwaysHarvestable, shovelEffective, silkTouchOneOf(Dirt{}, g)).withBlastResistance(0.6) + return newBreakInfo(0.6, alwaysHarvestable, shovelEffective, silkTouchOneOf(Dirt{}, g)) } // EncodeItem ... diff --git a/server/block/iron.go b/server/block/iron.go index 79a401340..87903c995 100644 --- a/server/block/iron.go +++ b/server/block/iron.go @@ -19,7 +19,7 @@ func (i Iron) Instrument() sound.Instrument { func (i Iron) BreakInfo() BreakInfo { return newBreakInfo(5, func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierStone.HarvestLevel - }, pickaxeEffective, oneOf(i)) + }, pickaxeEffective, oneOf(i)).withBlastResistance(30) } // PowersBeacon ... diff --git a/server/block/iron_bars.go b/server/block/iron_bars.go index 869544633..f12056c29 100644 --- a/server/block/iron_bars.go +++ b/server/block/iron_bars.go @@ -13,7 +13,7 @@ type IronBars struct { // BreakInfo ... func (i IronBars) BreakInfo() BreakInfo { - return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(i)) + return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(i)).withBlastResistance(30) } // CanDisplace ... diff --git a/server/block/iron_ore.go b/server/block/iron_ore.go index e8a5556e0..5225a88d5 100644 --- a/server/block/iron_ore.go +++ b/server/block/iron_ore.go @@ -15,9 +15,13 @@ type IronOre struct { // BreakInfo ... func (i IronOre) BreakInfo() BreakInfo { - return newBreakInfo(i.Type.Hardness(), func(t item.Tool) bool { + b := newBreakInfo(i.Type.Hardness(), func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierStone.HarvestLevel }, pickaxeEffective, silkTouchOneOf(item.RawIron{}, i)) + if i.Type == DeepslateOre() { + b = b.withBlastResistance(9) + } + return b } // EncodeItem ... diff --git a/server/block/lapis_ore.go b/server/block/lapis_ore.go index c56f7d7e4..5d3909d99 100644 --- a/server/block/lapis_ore.go +++ b/server/block/lapis_ore.go @@ -16,9 +16,13 @@ type LapisOre struct { // BreakInfo ... func (l LapisOre) BreakInfo() BreakInfo { - return newBreakInfo(l.Type.Hardness(), func(t item.Tool) bool { + i := newBreakInfo(l.Type.Hardness(), func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierStone.HarvestLevel }, pickaxeEffective, silkTouchDrop(item.NewStack(item.LapisLazuli{}, rand.Intn(5)+4), item.NewStack(l, 1))).withXPDropRange(2, 5) + if l.Type == DeepslateOre() { + i = i.withBlastResistance(9) + } + return i } // EncodeItem ... diff --git a/server/block/nether_brick_fence.go b/server/block/nether_brick_fence.go index f02294afe..c0cc58db7 100644 --- a/server/block/nether_brick_fence.go +++ b/server/block/nether_brick_fence.go @@ -13,7 +13,7 @@ type NetherBrickFence struct { // BreakInfo ... func (n NetherBrickFence) BreakInfo() BreakInfo { - return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(n)) + return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(n)).withBlastResistance(30) } // CanDisplace ... diff --git a/server/block/nether_bricks.go b/server/block/nether_bricks.go index 5af190f21..d41b42d06 100644 --- a/server/block/nether_bricks.go +++ b/server/block/nether_bricks.go @@ -14,7 +14,7 @@ type NetherBricks struct { // BreakInfo ... func (n NetherBricks) BreakInfo() BreakInfo { - return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(n)) + return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(n)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/netherite.go b/server/block/netherite.go index 7eb9c2f46..3900ab172 100644 --- a/server/block/netherite.go +++ b/server/block/netherite.go @@ -14,7 +14,7 @@ type Netherite struct { func (n Netherite) BreakInfo() BreakInfo { return newBreakInfo(50, func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierDiamond.HarvestLevel - }, pickaxeEffective, oneOf(n)) + }, pickaxeEffective, oneOf(n)).withBlastResistance(3600) } // PowersBeacon ... diff --git a/server/block/obsidian.go b/server/block/obsidian.go index 71f34b121..0a076116e 100644 --- a/server/block/obsidian.go +++ b/server/block/obsidian.go @@ -41,5 +41,5 @@ func (o Obsidian) EncodeBlock() (string, map[string]any) { func (o Obsidian) BreakInfo() BreakInfo { return newBreakInfo(50, func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierDiamond.HarvestLevel - }, pickaxeEffective, oneOf(o)) + }, pickaxeEffective, oneOf(o)).withBlastResistance(6000) } diff --git a/server/block/ore_type.go b/server/block/ore_type.go index ba55b4973..cd9b20e41 100644 --- a/server/block/ore_type.go +++ b/server/block/ore_type.go @@ -66,7 +66,7 @@ func (o ore) Hardness() float64 { case 0: return 3 case 1: - return 4.5 + return 3.5 } panic("unknown ore type") } diff --git a/server/block/packed_mud.go b/server/block/packed_mud.go index 174ee21bf..e3f388763 100644 --- a/server/block/packed_mud.go +++ b/server/block/packed_mud.go @@ -7,7 +7,7 @@ type PackedMud struct { // BreakInfo ... func (p PackedMud) BreakInfo() BreakInfo { - return newBreakInfo(1, alwaysHarvestable, nothingEffective, oneOf(p)) + return newBreakInfo(1, alwaysHarvestable, nothingEffective, oneOf(p)).withBlastResistance(15) } // EncodeItem ... diff --git a/server/block/planks.go b/server/block/planks.go index 7d53ec467..07277e725 100644 --- a/server/block/planks.go +++ b/server/block/planks.go @@ -24,7 +24,7 @@ func (p Planks) FlammabilityInfo() FlammabilityInfo { // BreakInfo ... func (p Planks) BreakInfo() BreakInfo { - return newBreakInfo(2, alwaysHarvestable, axeEffective, oneOf(p)) + return newBreakInfo(2, alwaysHarvestable, axeEffective, oneOf(p)).withBlastResistance(15) } // RepairsWoodTools ... diff --git a/server/block/prismarine.go b/server/block/prismarine.go index e1083b1fe..63d2ad079 100644 --- a/server/block/prismarine.go +++ b/server/block/prismarine.go @@ -15,7 +15,7 @@ type Prismarine struct { // BreakInfo ... func (p Prismarine) BreakInfo() BreakInfo { - return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(p)) + return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(p)).withBlastResistance(30) } // EncodeItem ... @@ -33,6 +33,5 @@ func allPrismarine() (c []world.Block) { for _, t := range PrismarineTypes() { c = append(c, Prismarine{Type: t}) } - return } diff --git a/server/block/purpur.go b/server/block/purpur.go index bf4d9a2c2..3f786dccb 100644 --- a/server/block/purpur.go +++ b/server/block/purpur.go @@ -25,7 +25,7 @@ type ( // BreakInfo ... func (p Purpur) BreakInfo() BreakInfo { - return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(p)) + return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(p)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/raw_copper.go b/server/block/raw_copper.go index 3cf16748f..97fdb1c2d 100644 --- a/server/block/raw_copper.go +++ b/server/block/raw_copper.go @@ -14,7 +14,7 @@ type RawCopper struct { func (r RawCopper) BreakInfo() BreakInfo { return newBreakInfo(5, func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierStone.HarvestLevel - }, pickaxeEffective, oneOf(r)) + }, pickaxeEffective, oneOf(r)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/raw_gold.go b/server/block/raw_gold.go index 37205a1b9..c47082bbd 100644 --- a/server/block/raw_gold.go +++ b/server/block/raw_gold.go @@ -14,7 +14,7 @@ type RawGold struct { func (g RawGold) BreakInfo() BreakInfo { return newBreakInfo(5, func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierIron.HarvestLevel - }, pickaxeEffective, oneOf(g)) + }, pickaxeEffective, oneOf(g)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/raw_iron.go b/server/block/raw_iron.go index f420e9293..100919ee8 100644 --- a/server/block/raw_iron.go +++ b/server/block/raw_iron.go @@ -14,7 +14,7 @@ type RawIron struct { func (r RawIron) BreakInfo() BreakInfo { return newBreakInfo(5, func(t item.Tool) bool { return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierStone.HarvestLevel - }, pickaxeEffective, oneOf(r)) + }, pickaxeEffective, oneOf(r)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/reinforced_deepslate.go b/server/block/reinforced_deepslate.go index 62e13035d..c3c9e0623 100644 --- a/server/block/reinforced_deepslate.go +++ b/server/block/reinforced_deepslate.go @@ -8,7 +8,7 @@ type ReinforcedDeepslate struct { // BreakInfo ... func (r ReinforcedDeepslate) BreakInfo() BreakInfo { - return newBreakInfo(55, alwaysHarvestable, nothingEffective, oneOf(r)) + return newBreakInfo(55, alwaysHarvestable, nothingEffective, oneOf(r)).withBlastResistance(3600) } // EncodeItem ... diff --git a/server/block/sandstone_stairs.go b/server/block/sandstone_stairs.go index ea39de403..9a1dbf2ed 100644 --- a/server/block/sandstone_stairs.go +++ b/server/block/sandstone_stairs.go @@ -49,7 +49,11 @@ func (s SandstoneStairs) Model() world.BlockModel { // BreakInfo ... func (s SandstoneStairs) BreakInfo() BreakInfo { - return newBreakInfo(s.Type.Hardness(), pickaxeHarvestable, pickaxeEffective, oneOf(s)) + i := newBreakInfo(s.Type.Hardness(), pickaxeHarvestable, pickaxeEffective, oneOf(s)) + if s.Type == SmoothSandstone() { + i = i.withBlastResistance(30) + } + return i } // EncodeItem ... diff --git a/server/block/stained_terracotta.go b/server/block/stained_terracotta.go index a16bcc9a1..1e92afceb 100644 --- a/server/block/stained_terracotta.go +++ b/server/block/stained_terracotta.go @@ -23,7 +23,7 @@ func (t StainedTerracotta) SoilFor(block world.Block) bool { // BreakInfo ... func (t StainedTerracotta) BreakInfo() BreakInfo { - return newBreakInfo(1.25, pickaxeHarvestable, pickaxeEffective, oneOf(t)) + return newBreakInfo(1.25, pickaxeHarvestable, pickaxeEffective, oneOf(t)).withBlastResistance(21) } // EncodeItem ... diff --git a/server/block/stone.go b/server/block/stone.go index 3a73bfdde..c148ab2c8 100644 --- a/server/block/stone.go +++ b/server/block/stone.go @@ -30,24 +30,24 @@ type ( // BreakInfo ... func (s Stone) BreakInfo() BreakInfo { if s.Smooth { - return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(s)) + return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(s)).withBlastResistance(30) } - return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, silkTouchOneOf(Cobblestone{}, Stone{})) + return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, silkTouchOneOf(Cobblestone{}, Stone{})).withBlastResistance(30) } // BreakInfo ... func (g Granite) BreakInfo() BreakInfo { - return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(g)) + return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(g)).withBlastResistance(30) } // BreakInfo ... func (d Diorite) BreakInfo() BreakInfo { - return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(d)) + return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(d)).withBlastResistance(30) } // BreakInfo ... func (a Andesite) BreakInfo() BreakInfo { - return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(a)) + return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(a)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/stone_brick_stairs.go b/server/block/stone_brick_stairs.go index 82e302ce9..5178c8d1f 100644 --- a/server/block/stone_brick_stairs.go +++ b/server/block/stone_brick_stairs.go @@ -44,7 +44,7 @@ func (s StoneBrickStairs) Model() world.BlockModel { // BreakInfo ... func (s StoneBrickStairs) BreakInfo() BreakInfo { - return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(s)) + return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(s)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/stone_bricks.go b/server/block/stone_bricks.go index f9868408a..79023e05b 100644 --- a/server/block/stone_bricks.go +++ b/server/block/stone_bricks.go @@ -14,7 +14,7 @@ type StoneBricks struct { // BreakInfo ... func (c StoneBricks) BreakInfo() BreakInfo { - return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(c)) + return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(c)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/terracotta.go b/server/block/terracotta.go index 2ba779a9b..0490068a9 100644 --- a/server/block/terracotta.go +++ b/server/block/terracotta.go @@ -17,7 +17,7 @@ func (Terracotta) SoilFor(block world.Block) bool { // BreakInfo ... func (t Terracotta) BreakInfo() BreakInfo { - return newBreakInfo(1.25, pickaxeHarvestable, pickaxeEffective, oneOf(t)) + return newBreakInfo(1.25, pickaxeHarvestable, pickaxeEffective, oneOf(t)).withBlastResistance(21) } // EncodeItem ... diff --git a/server/block/tuff.go b/server/block/tuff.go index 19d1c8c49..24457951a 100644 --- a/server/block/tuff.go +++ b/server/block/tuff.go @@ -8,7 +8,7 @@ type Tuff struct { // BreakInfo ... func (t Tuff) BreakInfo() BreakInfo { - return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(t)) + return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(t)).withBlastResistance(30) } // EncodeItem ... diff --git a/server/block/wood_fence.go b/server/block/wood_fence.go index 972b503d3..47089275c 100644 --- a/server/block/wood_fence.go +++ b/server/block/wood_fence.go @@ -19,7 +19,7 @@ type WoodFence struct { // BreakInfo ... func (w WoodFence) BreakInfo() BreakInfo { - return newBreakInfo(2, alwaysHarvestable, axeEffective, oneOf(w)) + return newBreakInfo(2, alwaysHarvestable, axeEffective, oneOf(w)).withBlastResistance(15) } // CanDisplace ... diff --git a/server/block/wood_fence_gate.go b/server/block/wood_fence_gate.go index c15d7e594..2c95b3e32 100644 --- a/server/block/wood_fence_gate.go +++ b/server/block/wood_fence_gate.go @@ -27,7 +27,7 @@ type WoodFenceGate struct { // BreakInfo ... func (f WoodFenceGate) BreakInfo() BreakInfo { - return newBreakInfo(2, alwaysHarvestable, axeEffective, oneOf(f)) + return newBreakInfo(2, alwaysHarvestable, axeEffective, oneOf(f)).withBlastResistance(15) } // FlammabilityInfo ... diff --git a/server/block/wood_slab.go b/server/block/wood_slab.go index f7b8ca768..1aebfc563 100644 --- a/server/block/wood_slab.go +++ b/server/block/wood_slab.go @@ -80,7 +80,7 @@ func (s WoodSlab) BreakInfo() BreakInfo { return []item.Stack{item.NewStack(s, 2)} } return []item.Stack{item.NewStack(s, 1)} - }) + }).withBlastResistance(15) } // LightDiffusionLevel returns 0 if the slab is a half slab, or 15 if it is double. diff --git a/server/block/wood_stairs.go b/server/block/wood_stairs.go index 6123b4628..b35216360 100644 --- a/server/block/wood_stairs.go +++ b/server/block/wood_stairs.go @@ -54,7 +54,7 @@ func (s WoodStairs) Model() world.BlockModel { // BreakInfo ... func (s WoodStairs) BreakInfo() BreakInfo { - return newBreakInfo(2, alwaysHarvestable, axeEffective, oneOf(s)) + return newBreakInfo(2, alwaysHarvestable, axeEffective, oneOf(s)).withBlastResistance(15) } // EncodeItem ... diff --git a/server/item/inventory/inventory.go b/server/item/inventory/inventory.go index 67fc9acfd..7373dfee0 100644 --- a/server/item/inventory/inventory.go +++ b/server/item/inventory/inventory.go @@ -25,7 +25,7 @@ type Inventory struct { // ErrSlotOutOfRange is returned by any methods on inventory when a slot is passed which is not within the // range of valid values for the inventory. -var ErrSlotOutOfRange = errors.New("slot is out of range: must be in range 0 <= slot < inventory.Size()") +var ErrSlotOutOfRange = errors.New("slot is out of range: must be in range 0 <= slot < inventory.Radius()") // New creates a new inventory with the size passed. The inventory size cannot be changed after it has been // constructed. @@ -44,7 +44,7 @@ func New(size int, f func(slot int, item item.Stack)) *Inventory { // Item attempts to obtain an item from a specific slot in the inventory. If an item was present in that slot, // the item is returned and the error is nil. If no item was present in the slot, a Stack with air as its item // and a count of 0 is returned. Stack.Empty() may be called to check if this is the case. -// Item only returns an error if the slot passed is out of range. (0 <= slot < inventory.Size()) +// Item only returns an error if the slot passed is out of range. (0 <= slot < inventory.Radius()) func (inv *Inventory) Item(slot int) (item.Stack, error) { inv.check() if !inv.validSlot(slot) { @@ -59,7 +59,7 @@ func (inv *Inventory) Item(slot int) (item.Stack, error) { // SetItem sets a stack of items to a specific slot in the inventory. If an item is already present in the // slot, that item will be overwritten. -// SetItem will return an error if the slot passed is out of range. (0 <= slot < inventory.Size()) +// SetItem will return an error if the slot passed is out of range. (0 <= slot < inventory.Radius()) func (inv *Inventory) SetItem(slot int, item item.Stack) error { inv.check() if !inv.validSlot(slot) {