diff --git a/go.mod b/go.mod index a8556f214..2b49fe906 100644 --- a/go.mod +++ b/go.mod @@ -1,21 +1,21 @@ module github.com/df-mc/dragonfly -go 1.23 +go 1.23.3 require ( github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9 github.com/cespare/xxhash/v2 v2.3.0 github.com/df-mc/goleveldb v1.1.9 github.com/df-mc/worldupgrader v1.0.18 - github.com/go-gl/mathgl v1.1.0 + github.com/go-gl/mathgl v1.2.0 github.com/google/uuid v1.6.0 github.com/pelletier/go-toml v1.9.5 github.com/sandertv/gophertunnel v1.43.0 github.com/segmentio/fasthash v1.0.3 - golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c - golang.org/x/mod v0.21.0 - golang.org/x/text v0.19.0 - golang.org/x/tools v0.26.0 + golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 + golang.org/x/mod v0.22.0 + golang.org/x/text v0.21.0 + golang.org/x/tools v0.28.0 ) require ( @@ -24,10 +24,9 @@ require ( github.com/klauspost/compress v1.17.11 // indirect github.com/muhammadmuzzammil1998/jsonc v1.0.0 // indirect github.com/sandertv/go-raknet v1.14.2 // indirect - golang.org/x/crypto v0.28.0 // indirect - golang.org/x/image v0.21.0 // indirect - golang.org/x/net v0.30.0 // indirect - golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.8.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/oauth2 v0.24.0 // indirect + golang.org/x/sync v0.10.0 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect ) diff --git a/go.sum b/go.sum index fe9041725..918d0d3bd 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/df-mc/goleveldb v1.1.9/go.mod h1:+NHCup03Sci5q84APIA21z3iPZCuk6m6ABtg github.com/df-mc/worldupgrader v1.0.18 h1:Q34X9ID/hGuDyj9oiq+dpyjOaJdNxhVmVUepf/EPYDA= github.com/df-mc/worldupgrader v1.0.18/go.mod h1:tsSOLTRm9mpG7VHvYpAjjZrkRHWmSbKZAm9bOLNnlDk= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-gl/mathgl v1.1.0 h1:0lzZ+rntPX3/oGrDzYGdowSLC2ky8Osirvf5uAwfIEA= -github.com/go-gl/mathgl v1.1.0/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ= +github.com/go-gl/mathgl v1.2.0 h1:v2eOj/y1B2afDxF6URV1qCYmo1KW08lAMtTbOn3KXCY= +github.com/go-gl/mathgl v1.2.0/go.mod h1:pf9+b5J3LFP7iZ4XXaVzZrCle0Q/vNpB/vDe5+3ulRE= github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -53,33 +53,30 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= -golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s= -golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= +golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -89,8 +86,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -102,14 +99,14 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= diff --git a/server/block/beetroot_seeds.go b/server/block/beetroot_seeds.go index 71e585a75..5776284ac 100644 --- a/server/block/beetroot_seeds.go +++ b/server/block/beetroot_seeds.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // BeetrootSeeds are a crop that can be harvested to craft soup or red dye. @@ -53,7 +53,7 @@ func (b BeetrootSeeds) BreakInfo() BreakInfo { if b.Growth < 7 { return []item.Stack{item.NewStack(b, 1)} } - return []item.Stack{item.NewStack(item.Beetroot{}, 1), item.NewStack(b, rand.Intn(4)+1)} + return []item.Stack{item.NewStack(item.Beetroot{}, 1), item.NewStack(b, rand.IntN(4)+1)} }) } @@ -71,7 +71,7 @@ func (b BeetrootSeeds) EncodeItem() (name string, meta int16) { func (b BeetrootSeeds) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { if tx.Light(pos) < 8 { breakBlock(b, pos, tx) - } else if b.Growth < 7 && r.Intn(3) > 0 && r.Float64() <= b.CalculateGrowthChance(pos, tx) { + } else if b.Growth < 7 && r.IntN(3) > 0 && r.Float64() <= b.CalculateGrowthChance(pos, tx) { b.Growth++ tx.SetBlock(pos, b, nil) } diff --git a/server/block/blackstone.go b/server/block/blackstone.go index 7515ba3ca..46756d691 100644 --- a/server/block/blackstone.go +++ b/server/block/blackstone.go @@ -3,7 +3,7 @@ package block import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" - "math/rand" + "math/rand/v2" ) // Blackstone is a naturally generating block in the nether that can be used to craft stone tools, brewing stands and @@ -22,7 +22,7 @@ func (b Blackstone) BreakInfo() BreakInfo { if b.Type == GildedBlackstone() { drops = func(item.Tool, []item.Enchantment) []item.Stack { if rand.Float64() < 0.1 { - return []item.Stack{item.NewStack(item.GoldNugget{}, rand.Intn(4)+2)} + return []item.Stack{item.NewStack(item.GoldNugget{}, rand.IntN(4)+2)} } return []item.Stack{item.NewStack(b, 1)} } diff --git a/server/block/blast_furnace.go b/server/block/blast_furnace.go index 91ef43c5d..f76f5c8b2 100644 --- a/server/block/blast_furnace.go +++ b/server/block/blast_furnace.go @@ -7,7 +7,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/block/block.go b/server/block/block.go index 09b0130a6..164b02eb2 100644 --- a/server/block/block.go +++ b/server/block/block.go @@ -8,7 +8,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/block/break_info.go b/server/block/break_info.go index 46d2cd2ff..7be767c81 100644 --- a/server/block/break_info.go +++ b/server/block/break_info.go @@ -7,7 +7,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/particle" "math" - "math/rand" + "math/rand/v2" "slices" "time" ) @@ -133,7 +133,7 @@ type XPDropRange [2]int func (r XPDropRange) RandomValue() int { diff := r[1] - r[0] // Add one because it's a [r[0], r[1]] interval. - return rand.Intn(diff+1) + r[0] + return rand.IntN(diff+1) + r[0] } // pickaxeEffective is a convenience function for blocks that are effectively mined with a pickaxe. diff --git a/server/block/cactus.go b/server/block/cactus.go index 490d1204d..5f56e03ee 100644 --- a/server/block/cactus.go +++ b/server/block/cactus.go @@ -6,7 +6,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // Cactus is a plant block that generates naturally in dry areas and causes damage. diff --git a/server/block/campfire.go b/server/block/campfire.go index 7997c2612..8544f7b7d 100644 --- a/server/block/campfire.go +++ b/server/block/campfire.go @@ -8,7 +8,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "strconv" "time" ) diff --git a/server/block/carrot.go b/server/block/carrot.go index 594dd7bf1..b11763ef8 100644 --- a/server/block/carrot.go +++ b/server/block/carrot.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) @@ -41,7 +41,7 @@ func (c Carrot) BoneMeal(pos cube.Pos, tx *world.Tx) bool { if c.Growth == 7 { return false } - c.Growth = min(c.Growth+rand.Intn(4)+2, 7) + c.Growth = min(c.Growth+rand.IntN(4)+2, 7) tx.SetBlock(pos, c, nil) return true } @@ -67,7 +67,7 @@ func (c Carrot) BreakInfo() BreakInfo { if c.Growth < 7 { return []item.Stack{item.NewStack(c, 1)} } - return []item.Stack{item.NewStack(c, rand.Intn(4)+2)} + return []item.Stack{item.NewStack(c, rand.IntN(4)+2)} }) } diff --git a/server/block/cocoa_bean.go b/server/block/cocoa_bean.go index b30707fd0..24bd50426 100644 --- a/server/block/cocoa_bean.go +++ b/server/block/cocoa_bean.go @@ -6,7 +6,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // CocoaBean is a crop block found in jungle biomes. @@ -79,7 +79,7 @@ func (c CocoaBean) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, tx *wo // RandomTick ... func (c CocoaBean) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { - if c.Age < 2 && r.Intn(5) == 0 { + if c.Age < 2 && r.IntN(5) == 0 { c.Age++ tx.SetBlock(pos, c, nil) } @@ -89,7 +89,7 @@ func (c CocoaBean) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { func (c CocoaBean) BreakInfo() BreakInfo { return newBreakInfo(0.2, alwaysHarvestable, axeEffective, func(item.Tool, []item.Enchantment) []item.Stack { if c.Age == 2 { - return []item.Stack{item.NewStack(c, rand.Intn(2)+2)} + return []item.Stack{item.NewStack(c, rand.IntN(2)+2)} } return []item.Stack{item.NewStack(c, 1)} }).withBlastResistance(15) diff --git a/server/block/composter.go b/server/block/composter.go index 82b00017b..2ebb24e98 100644 --- a/server/block/composter.go +++ b/server/block/composter.go @@ -7,7 +7,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/particle" "github.com/df-mc/dragonfly/server/world/sound" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/block/copper.go b/server/block/copper.go index 53c6f9368..c6671d139 100644 --- a/server/block/copper.go +++ b/server/block/copper.go @@ -6,7 +6,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // Copper is a solid block commonly found in deserts and beaches underneath sand. diff --git a/server/block/copper_door.go b/server/block/copper_door.go index b08770a1d..fdc8cc3e9 100644 --- a/server/block/copper_door.go +++ b/server/block/copper_door.go @@ -7,7 +7,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // CopperDoor is a block that can be used as an openable 1x2 barrier. diff --git a/server/block/copper_grate.go b/server/block/copper_grate.go index 38546d5f9..b0f91531e 100644 --- a/server/block/copper_grate.go +++ b/server/block/copper_grate.go @@ -6,7 +6,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // CopperGrate is a solid block commonly found in deserts and beaches underneath sand. diff --git a/server/block/copper_ore.go b/server/block/copper_ore.go index d68099b74..0f9aabb59 100644 --- a/server/block/copper_ore.go +++ b/server/block/copper_ore.go @@ -2,7 +2,7 @@ package block import ( "github.com/df-mc/dragonfly/server/item" - "math/rand" + "math/rand/v2" ) // CopperOre is a rare mineral block found underground. @@ -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))).withBlastResistance(9) + }, pickaxeEffective, silkTouchDrop(item.NewStack(item.RawCopper{}, rand.IntN(4)+2), item.NewStack(c, 1))).withBlastResistance(9) } // SmeltInfo ... diff --git a/server/block/copper_trapdoor.go b/server/block/copper_trapdoor.go index 6bb85866d..55b82b3c5 100644 --- a/server/block/copper_trapdoor.go +++ b/server/block/copper_trapdoor.go @@ -8,7 +8,7 @@ import ( "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" "math" - "math/rand" + "math/rand/v2" ) // CopperTrapdoor is a block that can be used as an openable 1x1 barrier. diff --git a/server/block/coral.go b/server/block/coral.go index e2b124f38..5b193fdcf 100644 --- a/server/block/coral.go +++ b/server/block/coral.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/block/coral_block.go b/server/block/coral_block.go index 3fd89eeee..2639d299f 100644 --- a/server/block/coral_block.go +++ b/server/block/coral_block.go @@ -3,7 +3,7 @@ package block import ( "github.com/df-mc/dragonfly/server/block/cube" "github.com/df-mc/dragonfly/server/world" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/block/deadbush.go b/server/block/deadbush.go index 218341e65..463566ecc 100644 --- a/server/block/deadbush.go +++ b/server/block/deadbush.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // DeadBush is a transparent block in the form of an aesthetic plant. @@ -55,7 +55,7 @@ func (d DeadBush) BreakInfo() BreakInfo { if t.ToolType() == item.TypeShears { return []item.Stack{item.NewStack(d, 1)} } - if amount := rand.Intn(3); amount != 0 { + if amount := rand.IntN(3); amount != 0 { return []item.Stack{item.NewStack(item.Stick{}, amount)} } return nil diff --git a/server/block/double_tall_grass.go b/server/block/double_tall_grass.go index e4e897856..d0675b595 100644 --- a/server/block/double_tall_grass.go +++ b/server/block/double_tall_grass.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // DoubleTallGrass is a two-block high variety of grass. diff --git a/server/block/dragon_egg.go b/server/block/dragon_egg.go index 276ce417f..56b184f9a 100644 --- a/server/block/dragon_egg.go +++ b/server/block/dragon_egg.go @@ -1,7 +1,7 @@ package block import ( - "math/rand" + "math/rand/v2" "github.com/df-mc/dragonfly/server/block/cube" "github.com/df-mc/dragonfly/server/item" @@ -30,7 +30,7 @@ func (d DragonEgg) SideClosed(cube.Pos, cube.Pos, *world.Tx) bool { // teleport ... func (d DragonEgg) teleport(pos cube.Pos, tx *world.Tx) { for i := 0; i < 1000; i++ { - newPos := pos.Add(cube.Pos{rand.Intn(31) - 15, max(tx.Range()[0]-pos.Y(), min(tx.Range()[1]-pos.Y(), rand.Intn(15)-7)), rand.Intn(31) - 15}) + newPos := pos.Add(cube.Pos{rand.IntN(31) - 15, max(tx.Range()[0]-pos.Y(), min(tx.Range()[1]-pos.Y(), rand.IntN(15)-7)), rand.IntN(31) - 15}) if _, ok := tx.Block(newPos).(Air); ok { tx.SetBlock(newPos, d, nil) diff --git a/server/block/explosion.go b/server/block/explosion.go index 5fc793e37..d2f6da3f6 100644 --- a/server/block/explosion.go +++ b/server/block/explosion.go @@ -9,7 +9,7 @@ import ( "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" "math" - "math/rand" + "math/rand/v2" "time" ) @@ -18,8 +18,10 @@ import ( type ExplosionConfig struct { // Size is the size of the explosion, it is effectively the radius which entities/blocks will be affected within. Size float64 - // Rand is the source to use for the explosion "randomness". - Rand rand.Source + // RandSource is the source to use for the explosion "randomness". If set + // to nil, RandSource defaults to a `rand.PCG`source seeded with + // `time.Now().UnixNano()`. + RandSource rand.Source // SpawnFire will cause the explosion to randomly start fires in 1/3 of all destroyed air blocks that are // above opaque blocks. SpawnFire bool @@ -74,8 +76,9 @@ func (c ExplosionConfig) Explode(tx *world.Tx, explosionPos mgl64.Vec3) { if c.Particle == nil { c.Particle = particle.HugeExplosion{} } - if c.Rand == nil { - c.Rand = rand.NewSource(time.Now().UnixNano()) + if c.RandSource == nil { + t := uint64(time.Now().UnixNano()) + c.RandSource = rand.NewPCG(t, t) } if c.Size == 0 { c.Size = 4 @@ -84,7 +87,7 @@ func (c ExplosionConfig) Explode(tx *world.Tx, explosionPos mgl64.Vec3) { c.ItemDropChance = 1.0 / c.Size } - r, d := rand.New(c.Rand), c.Size*2 + r, d := rand.New(c.RandSource), c.Size*2 box := cube.Box( math.Floor(explosionPos[0]-d-1), math.Floor(explosionPos[1]-d-1), @@ -164,7 +167,7 @@ func (c ExplosionConfig) Explode(tx *world.Tx, explosionPos mgl64.Vec3) { } if c.SpawnFire { for _, pos := range affectedBlocks { - if r.Intn(3) == 0 { + if r.IntN(3) == 0 { if _, ok := tx.Block(pos).(Air); ok && tx.Block(pos.Side(cube.FaceDown)).Model().FaceSolid(pos, cube.FaceUp, tx) { Fire{}.Start(tx, pos) } diff --git a/server/block/farmland.go b/server/block/farmland.go index d18d12b21..52fd73ce1 100644 --- a/server/block/farmland.go +++ b/server/block/farmland.go @@ -4,7 +4,7 @@ import ( "github.com/df-mc/dragonfly/server/block/cube" "github.com/df-mc/dragonfly/server/event" "github.com/df-mc/dragonfly/server/world" - "math/rand" + "math/rand/v2" ) // Farmland is a block that crops are grown on. Farmland is created by interacting with a grass or dirt block using a diff --git a/server/block/fern.go b/server/block/fern.go index 2af367ab7..50915910d 100644 --- a/server/block/fern.go +++ b/server/block/fern.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // Fern is a transparent plant block which can be used to obtain seeds and as decoration. diff --git a/server/block/fire.go b/server/block/fire.go index 2c407537c..76cea0f2e 100644 --- a/server/block/fire.go +++ b/server/block/fire.go @@ -8,7 +8,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/item/enchantment" "github.com/df-mc/dragonfly/server/world" - "math/rand" + "math/rand/v2" "time" ) @@ -55,8 +55,8 @@ func infinitelyBurning(pos cube.Pos, tx *world.Tx) bool { // burn attempts to burn a block. func (f Fire) burn(from, to cube.Pos, tx *world.Tx, r *rand.Rand, chanceBound int) { - if flammable, ok := tx.Block(to).(Flammable); ok && r.Intn(chanceBound) < flammable.FlammabilityInfo().Flammability { - if r.Intn(f.Age+10) < 5 && !rainingAround(to, tx) { + if flammable, ok := tx.Block(to).(Flammable); ok && r.IntN(chanceBound) < flammable.FlammabilityInfo().Flammability { + if r.IntN(f.Age+10) < 5 && !rainingAround(to, tx) { f.spread(from, to, tx, r) return } @@ -86,18 +86,18 @@ func (f Fire) tick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { return } infinitelyBurns := infinitelyBurning(pos, tx) - if !infinitelyBurns && (20+f.Age*3) > r.Intn(100) && rainingAround(pos, tx) { + if !infinitelyBurns && (20+f.Age*3) > r.IntN(100) && rainingAround(pos, tx) { // Fire is extinguished by the rain. tx.SetBlock(pos, nil, nil) return } - if f.Age < 15 && r.Intn(3) == 0 { + if f.Age < 15 && r.IntN(3) == 0 { f.Age++ tx.SetBlock(pos, f, nil) } - tx.ScheduleBlockUpdate(pos, f, time.Duration(30+r.Intn(10))*time.Second/20) + tx.ScheduleBlockUpdate(pos, f, time.Duration(30+r.IntN(10))*time.Second/20) if !infinitelyBurns { _, waterBelow := tx.Block(pos.Side(cube.FaceDown)).(Water) @@ -111,7 +111,7 @@ func (f Fire) tick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { } return } - if !flammableBlock(tx.Block(pos.Side(cube.FaceDown))) && f.Age == 15 && r.Intn(4) == 0 { + if !flammableBlock(tx.Block(pos.Side(cube.FaceDown))) && f.Age == 15 && r.IntN(4) == 0 { tx.SetBlock(pos, nil, nil) return } @@ -163,7 +163,7 @@ func (f Fire) tick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { maxChance /= 2 } - if maxChance > 0 && r.Intn(randomBound) <= maxChance && !rainingAround(blockPos, tx) { + if maxChance > 0 && r.IntN(randomBound) <= maxChance && !rainingAround(blockPos, tx) { f.spread(pos, blockPos, tx, r) } } @@ -184,9 +184,9 @@ func (f Fire) spread(from, to cube.Pos, tx *world.Tx, r *rand.Rand) { if tx.World().Handler().HandleFireSpread(ctx, from, to); ctx.Cancelled() { return } - spread := Fire{Type: f.Type, Age: min(15, f.Age+r.Intn(5)/4)} + spread := Fire{Type: f.Type, Age: min(15, f.Age+r.IntN(5)/4)} tx.SetBlock(to, spread, nil) - tx.ScheduleBlockUpdate(to, spread, time.Duration(30+r.Intn(10))*time.Second/20) + tx.ScheduleBlockUpdate(to, spread, time.Duration(30+r.IntN(10))*time.Second/20) } // EntityInside ... @@ -267,7 +267,7 @@ func (f Fire) Start(tx *world.Tx, pos cube.Pos) { if below.Model().FaceSolid(pos, cube.FaceUp, tx) || neighboursFlammable(pos, tx) { f := Fire{} tx.SetBlock(pos, f, nil) - tx.ScheduleBlockUpdate(pos, f, time.Duration(30+rand.Intn(10))*time.Second/20) + tx.ScheduleBlockUpdate(pos, f, time.Duration(30+rand.IntN(10))*time.Second/20) } } } diff --git a/server/block/flower.go b/server/block/flower.go index 0be651570..a294444e6 100644 --- a/server/block/flower.go +++ b/server/block/flower.go @@ -6,7 +6,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) @@ -38,7 +38,7 @@ func (f Flower) BoneMeal(pos cube.Pos, tx *world.Tx) (success bool) { } for i := 0; i < 8; i++ { - p := pos.Add(cube.Pos{rand.Intn(7) - 3, rand.Intn(3) - 1, rand.Intn(7) - 3}) + p := pos.Add(cube.Pos{rand.IntN(7) - 3, rand.IntN(3) - 1, rand.IntN(7) - 3}) if _, ok := tx.Block(p).(Air); !ok { continue } diff --git a/server/block/furnace.go b/server/block/furnace.go index 0b2e190e9..0399c8d11 100644 --- a/server/block/furnace.go +++ b/server/block/furnace.go @@ -7,7 +7,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/block/glowstone.go b/server/block/glowstone.go index 932aa3a12..905ff5b58 100644 --- a/server/block/glowstone.go +++ b/server/block/glowstone.go @@ -3,7 +3,7 @@ package block import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world/sound" - "math/rand" + "math/rand/v2" ) // Glowstone is commonly found on the ceiling of the nether dimension. @@ -18,7 +18,7 @@ func (g Glowstone) Instrument() sound.Instrument { // BreakInfo ... func (g Glowstone) BreakInfo() BreakInfo { - return newBreakInfo(0.3, alwaysHarvestable, nothingEffective, silkTouchDrop(item.NewStack(item.GlowstoneDust{}, rand.Intn(3)+2), item.NewStack(g, 1))) + return newBreakInfo(0.3, alwaysHarvestable, nothingEffective, silkTouchDrop(item.NewStack(item.GlowstoneDust{}, rand.IntN(3)+2), item.NewStack(g, 1))) } // EncodeItem ... diff --git a/server/block/grass.go b/server/block/grass.go index 6d85c53e5..10dd0e1aa 100644 --- a/server/block/grass.go +++ b/server/block/grass.go @@ -3,7 +3,7 @@ package block import ( "github.com/df-mc/dragonfly/server/block/cube" "github.com/df-mc/dragonfly/server/world" - "math/rand" + "math/rand/v2" ) // Grass blocks generate abundantly across the surface of the world. @@ -37,7 +37,7 @@ func init() { // SoilFor ... func (g Grass) SoilFor(block world.Block) bool { switch block.(type) { - case ShortGrass, Fern, DoubleTallGrass, Flower, DoubleFlower, NetherSprouts, PinkPetals, SugarCane: + case ShortGrass, Fern, DoubleTallGrass, Flower, DoubleFlower, NetherSprouts, PinkPetals, SugarCane, DeadBush: return true } return false @@ -80,12 +80,12 @@ func (g Grass) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { // BoneMeal ... func (g Grass) BoneMeal(pos cube.Pos, tx *world.Tx) bool { for i := 0; i < 14; i++ { - c := pos.Add(cube.Pos{rand.Intn(6) - 3, 0, rand.Intn(6) - 3}) + c := pos.Add(cube.Pos{rand.IntN(6) - 3, 0, rand.IntN(6) - 3}) above := c.Side(cube.FaceUp) _, air := tx.Block(above).(Air) _, grass := tx.Block(c).(Grass) if air && grass { - tx.SetBlock(above, plantSelection[rand.Intn(len(plantSelection))], nil) + tx.SetBlock(above, plantSelection[rand.IntN(len(plantSelection))], nil) } } diff --git a/server/block/gravel.go b/server/block/gravel.go index 9d98c757b..6fdf195c1 100644 --- a/server/block/gravel.go +++ b/server/block/gravel.go @@ -4,7 +4,7 @@ import ( "github.com/df-mc/dragonfly/server/block/cube" "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" - "math/rand" + "math/rand/v2" ) // Gravel is a block affected by gravity. It has a 10% chance of dropping flint instead of itself on break. diff --git a/server/block/item_frame.go b/server/block/item_frame.go index 96630358f..8a66ad05e 100644 --- a/server/block/item_frame.go +++ b/server/block/item_frame.go @@ -8,7 +8,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // ItemFrame is a block entity that displays the item or block that is inside it. diff --git a/server/block/kelp.go b/server/block/kelp.go index 336c509ed..795b9c06f 100644 --- a/server/block/kelp.go +++ b/server/block/kelp.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // Kelp is an underwater block which can grow on top of solids underwater. @@ -70,7 +70,7 @@ func (Kelp) SideClosed(cube.Pos, cube.Pos, *world.Tx) bool { // withRandomAge returns a new Kelp block with its age value randomized between 0 and 24. func (k Kelp) withRandomAge() Kelp { - k.Age = rand.Intn(25) + k.Age = rand.IntN(25) return k } @@ -124,7 +124,7 @@ func (k Kelp) NeighbourUpdateTick(pos, changedNeighbour cube.Pos, tx *world.Tx) // RandomTick ... func (k Kelp) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { // Every random tick, there's a 14% chance for Kelp to grow if its age is below 25. - if r.Intn(100) < 15 && k.Age < 25 { + if r.IntN(100) < 15 && k.Age < 25 { abovePos := pos.Side(cube.FaceUp) liquid, ok := tx.Liquid(abovePos) diff --git a/server/block/lapis_ore.go b/server/block/lapis_ore.go index c8b427117..22e5d9388 100644 --- a/server/block/lapis_ore.go +++ b/server/block/lapis_ore.go @@ -2,7 +2,7 @@ package block import ( "github.com/df-mc/dragonfly/server/item" - "math/rand" + "math/rand/v2" ) // LapisOre is an ore block from which lapis lazuli is obtained. @@ -18,7 +18,7 @@ type LapisOre struct { func (l LapisOre) BreakInfo() BreakInfo { 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) + }, 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) } diff --git a/server/block/lava.go b/server/block/lava.go index df4a2bce0..239b0ac0e 100644 --- a/server/block/lava.go +++ b/server/block/lava.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/event" "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" - "math/rand" + "math/rand/v2" "time" ) @@ -50,10 +50,10 @@ func (l Lava) EntityInside(_ cube.Pos, _ *world.Tx, e world.Entity) { // RandomTick ... func (l Lava) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { - i := r.Intn(3) + i := r.IntN(3) if i > 0 { for j := 0; j < i; j++ { - pos = pos.Add(cube.Pos{r.Intn(3) - 1, 1, r.Intn(3) - 1}) + pos = pos.Add(cube.Pos{r.IntN(3) - 1, 1, r.IntN(3) - 1}) if _, ok := tx.Block(pos).(Air); ok { if neighboursLavaFlammable(pos, tx) { Fire{}.Start(tx, pos) @@ -62,7 +62,7 @@ func (l Lava) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { } } else { for j := 0; j < 3; j++ { - pos = pos.Add(cube.Pos{r.Intn(3) - 1, 0, r.Intn(3) - 1}) + pos = pos.Add(cube.Pos{r.IntN(3) - 1, 0, r.IntN(3) - 1}) if _, ok := tx.Block(pos.Side(cube.FaceUp)).(Air); ok { if flammable, ok := tx.Block(pos).(Flammable); ok && flammable.FlammabilityInfo().LavaFlammable && flammable.FlammabilityInfo().Encouragement > 0 { Fire{}.Start(tx, pos) diff --git a/server/block/leaves.go b/server/block/leaves.go index 7875ea537..9fa236c22 100644 --- a/server/block/leaves.go +++ b/server/block/leaves.go @@ -6,7 +6,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // Leaves are blocks that grow as part of trees which mainly drop saplings and sticks. @@ -106,7 +106,7 @@ func (l Leaves) BreakInfo() BreakInfo { var drops []item.Stack // TODO: Drop saplings. if rand.Float64() < 0.02 { - drops = append(drops, item.NewStack(item.Stick{}, rand.Intn(2)+1)) + drops = append(drops, item.NewStack(item.Stick{}, rand.IntN(2)+1)) } if (l.Wood == OakWood() || l.Wood == DarkOakWood()) && rand.Float64() < 0.005 { drops = append(drops, item.NewStack(item.Apple{}, 1)) diff --git a/server/block/melon.go b/server/block/melon.go index 93f338148..142d15f9e 100644 --- a/server/block/melon.go +++ b/server/block/melon.go @@ -2,7 +2,7 @@ package block import ( "github.com/df-mc/dragonfly/server/item" - "math/rand" + "math/rand/v2" ) // Melon is a fruit block that grows from melon stems. @@ -12,7 +12,7 @@ type Melon struct { // BreakInfo ... func (m Melon) BreakInfo() BreakInfo { - return newBreakInfo(1, alwaysHarvestable, axeEffective, silkTouchDrop(item.NewStack(item.MelonSlice{}, rand.Intn(5)+3), item.NewStack(m, 1))) + return newBreakInfo(1, alwaysHarvestable, axeEffective, silkTouchDrop(item.NewStack(item.MelonSlice{}, rand.IntN(5)+3), item.NewStack(m, 1))) } // CompostChance ... diff --git a/server/block/melon_seeds.go b/server/block/melon_seeds.go index 69c8bfe84..68bbaa2d7 100644 --- a/server/block/melon_seeds.go +++ b/server/block/melon_seeds.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // MelonSeeds grow melon blocks. @@ -47,7 +47,7 @@ func (m MelonSeeds) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { return } } - direction := directions[r.Intn(len(directions))].Face() + direction := directions[r.IntN(len(directions))].Face() stemPos := pos.Side(direction) if _, ok := tx.Block(stemPos).(Air); ok { switch tx.Block(stemPos.Side(cube.FaceDown)).(type) { @@ -66,7 +66,7 @@ func (m MelonSeeds) BoneMeal(pos cube.Pos, tx *world.Tx) bool { if m.Growth == 7 { return false } - m.Growth = min(m.Growth+rand.Intn(4)+2, 7) + m.Growth = min(m.Growth+rand.IntN(4)+2, 7) tx.SetBlock(pos, m, nil) return true } diff --git a/server/block/mud.go b/server/block/mud.go index 272bee672..13c225ee4 100644 --- a/server/block/mud.go +++ b/server/block/mud.go @@ -10,7 +10,7 @@ type Mud struct { // SoilFor ... func (Mud) SoilFor(block world.Block) bool { switch block.(type) { - case ShortGrass, Fern, DoubleTallGrass, Flower, DoubleFlower, NetherSprouts, PinkPetals: + case ShortGrass, Fern, DoubleTallGrass, Flower, DoubleFlower, NetherSprouts, PinkPetals, DeadBush: return true } return false diff --git a/server/block/nether_gold_ore.go b/server/block/nether_gold_ore.go index 7388c2456..293680ccc 100644 --- a/server/block/nether_gold_ore.go +++ b/server/block/nether_gold_ore.go @@ -2,7 +2,7 @@ package block import ( "github.com/df-mc/dragonfly/server/item" - "math/rand" + "math/rand/v2" ) // NetherGoldOre is a variant of gold ore found exclusively in The Nether. @@ -12,7 +12,7 @@ type NetherGoldOre struct { // BreakInfo ... func (n NetherGoldOre) BreakInfo() BreakInfo { - return newBreakInfo(3, pickaxeHarvestable, pickaxeEffective, silkTouchDrop(item.NewStack(item.GoldNugget{}, rand.Intn(4)+2), item.NewStack(n, 1))).withXPDropRange(0, 1) + return newBreakInfo(3, pickaxeHarvestable, pickaxeEffective, silkTouchDrop(item.NewStack(item.GoldNugget{}, rand.IntN(4)+2), item.NewStack(n, 1))).withXPDropRange(0, 1) } // SmeltInfo ... diff --git a/server/block/nether_wart.go b/server/block/nether_wart.go index a3bd0c1eb..da90ff151 100644 --- a/server/block/nether_wart.go +++ b/server/block/nether_wart.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // NetherWart is a fungus found in the Nether that is vital in the creation of potions. @@ -55,7 +55,7 @@ func (n NetherWart) NeighbourUpdateTick(pos, _ cube.Pos, tx *world.Tx) { func (n NetherWart) BreakInfo() BreakInfo { return newBreakInfo(0, alwaysHarvestable, nothingEffective, func(item.Tool, []item.Enchantment) []item.Stack { if n.Age == 3 { - return []item.Stack{item.NewStack(n, rand.Intn(3)+2)} + return []item.Stack{item.NewStack(n, rand.IntN(3)+2)} } return []item.Stack{item.NewStack(n, 1)} }) diff --git a/server/block/oxidizable.go b/server/block/oxidizable.go index 4a4616e14..4d3b6c5e1 100644 --- a/server/block/oxidizable.go +++ b/server/block/oxidizable.go @@ -3,7 +3,7 @@ package block import ( "github.com/df-mc/dragonfly/server/block/cube" "github.com/df-mc/dragonfly/server/world" - "math/rand" + "math/rand/v2" ) // Oxidisable is a block that can naturally oxidise over time, such as copper. diff --git a/server/block/potato.go b/server/block/potato.go index c4b6a0fc2..fdf9a871f 100644 --- a/server/block/potato.go +++ b/server/block/potato.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) @@ -46,7 +46,7 @@ func (p Potato) BoneMeal(pos cube.Pos, tx *world.Tx) bool { if p.Growth == 7 { return false } - p.Growth = min(p.Growth+rand.Intn(4)+2, 7) + p.Growth = min(p.Growth+rand.IntN(4)+2, 7) tx.SetBlock(pos, p, nil) return true } @@ -71,7 +71,7 @@ func (p Potato) BreakInfo() BreakInfo { return newBreakInfo(0, alwaysHarvestable, nothingEffective, func(item.Tool, []item.Enchantment) []item.Stack { n := 1 if p.Growth >= 7 { - n += rand.Intn(5) + n += rand.IntN(5) } if rand.Float64() < 0.02 { return []item.Stack{item.NewStack(p, n), item.NewStack(item.PoisonousPotato{}, 1)} diff --git a/server/block/pumpkin_seeds.go b/server/block/pumpkin_seeds.go index 4cb982f3c..5a62c6507 100644 --- a/server/block/pumpkin_seeds.go +++ b/server/block/pumpkin_seeds.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // PumpkinSeeds grow pumpkin blocks. @@ -47,7 +47,7 @@ func (p PumpkinSeeds) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { return } } - direction := directions[r.Intn(len(directions))].Face() + direction := directions[r.IntN(len(directions))].Face() stemPos := pos.Side(direction) if _, ok := tx.Block(stemPos).(Air); ok { switch tx.Block(stemPos.Side(cube.FaceDown)).(type) { @@ -66,7 +66,7 @@ func (p PumpkinSeeds) BoneMeal(pos cube.Pos, tx *world.Tx) bool { if p.Growth == 7 { return false } - p.Growth = min(p.Growth+rand.Intn(4)+2, 7) + p.Growth = min(p.Growth+rand.IntN(4)+2, 7) tx.SetBlock(pos, p, nil) return true } diff --git a/server/block/sea_lantern.go b/server/block/sea_lantern.go index f5c822b23..69829edab 100644 --- a/server/block/sea_lantern.go +++ b/server/block/sea_lantern.go @@ -2,7 +2,7 @@ package block import ( "github.com/df-mc/dragonfly/server/item" - "math/rand" + "math/rand/v2" ) // SeaLantern is an underwater light sources that appear in ocean monuments and underwater ruins. @@ -19,7 +19,7 @@ func (SeaLantern) LightEmissionLevel() uint8 { // BreakInfo ... func (s SeaLantern) BreakInfo() BreakInfo { - return newBreakInfo(0.3, alwaysHarvestable, nothingEffective, silkTouchDrop(item.NewStack(item.PrismarineCrystals{}, rand.Intn(2)+2), item.NewStack(s, 1))) + return newBreakInfo(0.3, alwaysHarvestable, nothingEffective, silkTouchDrop(item.NewStack(item.PrismarineCrystals{}, rand.IntN(2)+2), item.NewStack(s, 1))) } // EncodeItem ... diff --git a/server/block/sea_pickle.go b/server/block/sea_pickle.go index 9a6472994..bfb7f07e6 100644 --- a/server/block/sea_pickle.go +++ b/server/block/sea_pickle.go @@ -6,7 +6,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" "math" - "math/rand" + "math/rand/v2" ) // SeaPickle is a small stationary underwater block that emits light, and is typically found in colonies of up to @@ -53,7 +53,7 @@ func (s SeaPickle) BoneMeal(pos cube.Pos, tx *world.Tx) bool { distance := -int(math.Abs(float64(x))) + 2 for z := -distance; z <= distance; z++ { for y := -1; y < 1; y++ { - if (x == 0 && y == 0 && z == 0) || rand.Intn(6) != 0 { + if (x == 0 && y == 0 && z == 0) || rand.IntN(6) != 0 { continue } newPos := pos.Add(cube.Pos{x, y, z}) @@ -64,7 +64,7 @@ func (s SeaPickle) BoneMeal(pos cube.Pos, tx *world.Tx) bool { if coral, ok := tx.Block(newPos.Side(cube.FaceDown)).(CoralBlock); !ok || coral.Dead { continue } - tx.SetBlock(newPos, SeaPickle{AdditionalCount: rand.Intn(3) + 1}, nil) + tx.SetBlock(newPos, SeaPickle{AdditionalCount: rand.IntN(3) + 1}, nil) } } } diff --git a/server/block/short_grass.go b/server/block/short_grass.go index e3d3c340c..b97260452 100644 --- a/server/block/short_grass.go +++ b/server/block/short_grass.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // ShortGrass is a transparent plant block which can be used to obtain seeds and as decoration. diff --git a/server/block/smelter.go b/server/block/smelter.go index 46d422eec..a1a131913 100644 --- a/server/block/smelter.go +++ b/server/block/smelter.go @@ -6,7 +6,7 @@ import ( "github.com/df-mc/dragonfly/server/item/inventory" "github.com/df-mc/dragonfly/server/world" "math" - "math/rand" + "math/rand/v2" "sync" "time" ) diff --git a/server/block/smoker.go b/server/block/smoker.go index f00830818..ecf3ba281 100644 --- a/server/block/smoker.go +++ b/server/block/smoker.go @@ -7,7 +7,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/block/sugar_cane.go b/server/block/sugar_cane.go index 7b099d325..1c6e21c2a 100644 --- a/server/block/sugar_cane.go +++ b/server/block/sugar_cane.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // SugarCane is a plant block that generates naturally near water. diff --git a/server/block/tnt.go b/server/block/tnt.go index b7f6ae06c..5ed5c81f8 100644 --- a/server/block/tnt.go +++ b/server/block/tnt.go @@ -7,7 +7,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) @@ -35,7 +35,7 @@ func (t TNT) Ignite(pos cube.Pos, tx *world.Tx, _ world.Entity) bool { // Explode ... func (t TNT) Explode(_ mgl64.Vec3, pos cube.Pos, tx *world.Tx, _ ExplosionConfig) { - spawnTnt(pos, tx, time.Second/2+time.Duration(rand.Intn(int(time.Second+time.Second/2)))) + spawnTnt(pos, tx, time.Second/2+time.Duration(rand.IntN(int(time.Second+time.Second/2)))) } // BreakInfo ... diff --git a/server/block/vine.go b/server/block/vine.go index a821f347f..1fe2b9560 100644 --- a/server/block/vine.go +++ b/server/block/vine.go @@ -6,7 +6,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // Vines are climbable non-solid vegetation blocks that grow on walls. @@ -159,7 +159,7 @@ func (v Vines) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { } // Choose a random direction to spread. - face := cube.Face(r.Intn(len(cube.Faces()))) + face := cube.Face(r.IntN(len(cube.Faces()))) selectedPos := pos.Side(face) // If a horizontal direction was chosen and the vine block is not already @@ -230,7 +230,7 @@ func (v Vines) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { // there is a 50% chance for the new above vine block to // attach onto the direction, if there is also a solid block // in that direction to support the vine. - if r.Intn(2) == 0 && v.Attachment(f.Direction()) && v.canSpreadTo(tx, selectedPos.Side(f)) { + if r.IntN(2) == 0 && v.Attachment(f.Direction()) && v.canSpreadTo(tx, selectedPos.Side(f)) { newVines = newVines.WithAttachment(f.Direction(), true) } } @@ -257,7 +257,7 @@ func (v Vines) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) { // For each direction the current vine block is attached on, there is a // 50% chance for the below vine block to attach onto the direction if // it is not already attached in that direction. - if r.Intn(2) == 0 && v.Attachment(f.Direction()) && !newVines.Attachment(f.Direction()) { + if r.IntN(2) == 0 && v.Attachment(f.Direction()) && !newVines.Attachment(f.Direction()) { newVines, changed = newVines.WithAttachment(f.Direction(), true), true } } diff --git a/server/block/water.go b/server/block/water.go index c34fb313d..cc830d66c 100644 --- a/server/block/water.go +++ b/server/block/water.go @@ -7,7 +7,7 @@ import ( "github.com/df-mc/dragonfly/server/item/potion" "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/block/wheat_seeds.go b/server/block/wheat_seeds.go index 3d2294d80..2ebb4659a 100644 --- a/server/block/wheat_seeds.go +++ b/server/block/wheat_seeds.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" ) // WheatSeeds are a crop that can be harvested to craft bread, cake, & cookies. @@ -24,7 +24,7 @@ func (s WheatSeeds) BoneMeal(pos cube.Pos, tx *world.Tx) bool { if s.Growth == 7 { return false } - s.Growth = min(s.Growth+rand.Intn(4)+2, 7) + s.Growth = min(s.Growth+rand.IntN(4)+2, 7) tx.SetBlock(pos, s, nil) return true } @@ -50,7 +50,7 @@ func (s WheatSeeds) BreakInfo() BreakInfo { if s.Growth < 7 { return []item.Stack{item.NewStack(s, 1)} } - return []item.Stack{item.NewStack(item.Wheat{}, 1), item.NewStack(s, rand.Intn(4)+1)} + return []item.Stack{item.NewStack(item.Wheat{}, 1), item.NewStack(s, rand.IntN(4)+1)} }) } diff --git a/server/cmd/argument.go b/server/cmd/argument.go index 4da062225..1b76ade3a 100644 --- a/server/cmd/argument.go +++ b/server/cmd/argument.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/internal/sliceutil" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "reflect" "slices" "sort" @@ -299,7 +299,7 @@ func (p parser) parseTargets(line *Line, tx *world.Tx) ([]Target, error) { if len(players) == 0 { return nil, nil } - return []Target{players[rand.Intn(len(players))]}, nil + return []Target{players[rand.IntN(len(players))]}, nil default: target, err := p.parsePlayer(first, players) if err != nil { diff --git a/server/entity/bottle_of_enchanting.go b/server/entity/bottle_of_enchanting.go index e268d3e11..153c604d9 100644 --- a/server/entity/bottle_of_enchanting.go +++ b/server/entity/bottle_of_enchanting.go @@ -6,7 +6,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/particle" "github.com/df-mc/dragonfly/server/world/sound" - "math/rand" + "math/rand/v2" ) // NewBottleOfEnchanting ... @@ -28,7 +28,7 @@ var bottleOfEnchantingConf = ProjectileBehaviourConfig{ // spawnExperience spawns experience orbs with a value of 3-11 at the target of // a trace.Result. func spawnExperience(_ *Ent, tx *world.Tx, target trace.Result) { - for _, orb := range NewExperienceOrbs(target.Position(), rand.Intn(9)+3) { + for _, orb := range NewExperienceOrbs(target.Position(), rand.IntN(9)+3) { tx.AddEntity(orb) } } diff --git a/server/entity/effect.go b/server/entity/effect.go index 95001779d..ba5997830 100644 --- a/server/entity/effect.go +++ b/server/entity/effect.go @@ -4,8 +4,9 @@ import ( "fmt" "github.com/df-mc/dragonfly/server/entity/effect" "github.com/df-mc/dragonfly/server/world" - "golang.org/x/exp/maps" + "maps" "reflect" + "slices" ) // EffectManager manages the effects of an entity. The effect manager will only store effects that last for @@ -77,7 +78,7 @@ func (m *EffectManager) Effect(e effect.Type) (effect.Effect, bool) { // Effects returns a list of all effects currently present in the effect manager. This will never include // effects that have expired. func (m *EffectManager) Effects() []effect.Effect { - return maps.Values(m.effects) + return slices.Collect(maps.Values(m.effects)) } // Tick ticks the EffectManager, applying all of its effects to the Living entity passed when applicable and diff --git a/server/entity/experience_orb.go b/server/entity/experience_orb.go index cb139655c..21b178822 100644 --- a/server/entity/experience_orb.go +++ b/server/entity/experience_orb.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/internal/nbtconv" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "slices" ) diff --git a/server/entity/falling_block_behaviour.go b/server/entity/falling_block_behaviour.go index 3e933d2e6..7ea9ea84f 100644 --- a/server/entity/falling_block_behaviour.go +++ b/server/entity/falling_block_behaviour.go @@ -7,7 +7,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" "math" - "math/rand" + "math/rand/v2" ) // FallingBlockBehaviourConfig holds optional parameters for diff --git a/server/entity/lightning.go b/server/entity/lightning.go index 45f054f42..46c3b6a53 100644 --- a/server/entity/lightning.go +++ b/server/entity/lightning.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) @@ -26,7 +26,7 @@ func NewLightningWithDamage(opts world.EntitySpawnOpts, dmg float64, blockFire b EntityFireDuration: entityFireDuration, BlockFire: blockFire, state: 2, - lifetime: rand.Intn(4) + 1, + lifetime: rand.IntN(4) + 1, }).tick return opts.New(LightningType, conf) } @@ -49,7 +49,7 @@ func (s *lightningState) tick(e *Ent, tx *world.Tx) { if s.state--; s.state < 0 { if s.lifetime == 0 { _ = e.Close() - } else if s.state < -rand.Intn(10) { + } else if s.state < -rand.IntN(10) { s.lifetime-- s.state = 1 @@ -86,7 +86,7 @@ func (s *lightningState) dealDamage(e *Ent, tx *world.Tx) { func (s *lightningState) spreadFire(tx *world.Tx, pos cube.Pos) { s.fire().Start(tx, pos) for i := 0; i < 4; i++ { - pos.Add(cube.Pos{rand.Intn(3) - 1, rand.Intn(3) - 1, rand.Intn(3) - 1}) + pos.Add(cube.Pos{rand.IntN(3) - 1, rand.IntN(3) - 1, rand.IntN(3) - 1}) s.fire().Start(tx, pos) } } diff --git a/server/entity/projectile.go b/server/entity/projectile.go index 80a3be352..4b07ecd55 100644 --- a/server/entity/projectile.go +++ b/server/entity/projectile.go @@ -10,7 +10,7 @@ import ( "github.com/go-gl/mathgl/mgl64" "iter" "math" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/entity/tnt.go b/server/entity/tnt.go index 85567127c..b151dd19a 100644 --- a/server/entity/tnt.go +++ b/server/entity/tnt.go @@ -7,7 +7,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" "math" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/internal/blockinternal/builder.go b/server/internal/blockinternal/builder.go index 233c660c2..ea4c72da1 100644 --- a/server/internal/blockinternal/builder.go +++ b/server/internal/blockinternal/builder.go @@ -2,7 +2,7 @@ package blockinternal import ( "github.com/df-mc/dragonfly/server/item/category" - "golang.org/x/exp/maps" + "maps" "slices" ) diff --git a/server/internal/iteminternal/builder.go b/server/internal/iteminternal/builder.go index bdc2e24e0..b1e694081 100644 --- a/server/internal/iteminternal/builder.go +++ b/server/internal/iteminternal/builder.go @@ -2,7 +2,7 @@ package iteminternal import ( "github.com/df-mc/dragonfly/server/item/category" - "golang.org/x/exp/maps" + "maps" "strings" ) diff --git a/server/item/chicken.go b/server/item/chicken.go index b4ed76de5..2db0d49c4 100644 --- a/server/item/chicken.go +++ b/server/item/chicken.go @@ -3,7 +3,7 @@ package item import ( "github.com/df-mc/dragonfly/server/entity/effect" "github.com/df-mc/dragonfly/server/world" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/item/enchantment.go b/server/item/enchantment.go index 85c67518e..ca8a9da46 100644 --- a/server/item/enchantment.go +++ b/server/item/enchantment.go @@ -2,7 +2,9 @@ package item import ( "github.com/df-mc/dragonfly/server/world" - "golang.org/x/exp/maps" + "maps" + "slices" + "sort" ) // Enchantment is an enchantment that can be applied to a Stack. It holds an EnchantmentType and level that influences @@ -86,5 +88,11 @@ func EnchantmentID(e EnchantmentType) (int, bool) { // Enchantments returns a slice of all registered enchantments. func Enchantments() []EnchantmentType { - return maps.Values(enchantmentsMap) + e := slices.Collect(maps.Values(enchantmentsMap)) + sort.Slice(e, func(i, j int) bool { + id1, _ := EnchantmentID(e[i]) + id2, _ := EnchantmentID(e[j]) + return id1 < id2 + }) + return e } diff --git a/server/item/enchantment/unbreaking.go b/server/item/enchantment/unbreaking.go index 3e1022a08..cb235f559 100644 --- a/server/item/enchantment/unbreaking.go +++ b/server/item/enchantment/unbreaking.go @@ -3,7 +3,7 @@ package enchantment import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" - "math/rand" + "math/rand/v2" ) // Unbreaking is an enchantment that gives a chance for an item to avoid @@ -50,7 +50,7 @@ func (unbreaking) Reduce(it world.Item, level, amount int) int { after := amount _, ok := it.(item.Armour) for i := 0; i < amount; i++ { - if (!ok || rand.Float64() >= 0.6) && rand.Intn(level+1) > 0 { + if (!ok || rand.Float64() >= 0.6) && rand.IntN(level+1) > 0 { after-- } } diff --git a/server/item/fire_charge.go b/server/item/fire_charge.go index 841ce2fc1..b74653b01 100644 --- a/server/item/fire_charge.go +++ b/server/item/fire_charge.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) @@ -30,7 +30,7 @@ func (f FireCharge) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, tx *w flame := fire() tx.SetBlock(s, flame, nil) - tx.ScheduleBlockUpdate(s, flame, time.Duration(30+rand.Intn(10))*time.Second/20) + tx.ScheduleBlockUpdate(s, flame, time.Duration(30+rand.IntN(10))*time.Second/20) return true } return false diff --git a/server/item/firework.go b/server/item/firework.go index 3f6af3185..0cd5f55db 100644 --- a/server/item/firework.go +++ b/server/item/firework.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) @@ -79,7 +79,7 @@ func (f Firework) DecodeNBT(data map[string]any) any { // RandomisedDuration returns the randomised flight duration of the firework. func (f Firework) RandomisedDuration() time.Duration { - return f.Duration + time.Duration(rand.Intn(int(time.Millisecond*600))) + return f.Duration + time.Duration(rand.IntN(int(time.Millisecond*600))) } // EncodeItem ... diff --git a/server/item/flint_and_steel.go b/server/item/flint_and_steel.go index 5bf6cade1..1e139dcbe 100644 --- a/server/item/flint_and_steel.go +++ b/server/item/flint_and_steel.go @@ -5,7 +5,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" - "math/rand" + "math/rand/v2" "time" ) @@ -41,7 +41,7 @@ func (f FlintAndSteel) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, tx flame := fire() tx.SetBlock(s, flame, nil) - tx.ScheduleBlockUpdate(s, flame, time.Duration(30+rand.Intn(10))*time.Second/20) + tx.ScheduleBlockUpdate(s, flame, time.Duration(30+rand.IntN(10))*time.Second/20) return true } return false diff --git a/server/item/inventory/armour.go b/server/item/inventory/armour.go index 17e073747..dad331c27 100644 --- a/server/item/inventory/armour.go +++ b/server/item/inventory/armour.go @@ -6,7 +6,7 @@ import ( "github.com/df-mc/dragonfly/server/item/enchantment" "github.com/df-mc/dragonfly/server/world" "math" - "math/rand" + "math/rand/v2" ) // Armour represents an inventory for armour. It has 4 slots, one for a helmet, chestplate, leggings and @@ -174,7 +174,7 @@ func (a *Armour) ThornsDamage(f DamageFunc) float64 { // 15%/level chance of thorns activation per item. Total damage from // normal thorns armour (max thorns III) should never exceed 4.0 in // total. - dmg = math.Min(dmg+float64(1+rand.Intn(4)), 4.0) + dmg = math.Min(dmg+float64(1+rand.IntN(4)), 4.0) } } if highest := a.HighestEnchantmentLevel(enchantment.Thorns); highest > 10 { @@ -191,7 +191,7 @@ func (a *Armour) ThornsDamage(f DamageFunc) float64 { // thorns armour item worn, while Bedrock Edition deals 1 additional damage // for every thorns item and another 2 for every thorns item when it // activates. - slot := rand.Intn(len(slots)) + slot := rand.IntN(len(slots)) _ = a.Inventory().SetItem(slot, f(slots[slot], 2)) } return dmg diff --git a/server/item/poisonous_potato.go b/server/item/poisonous_potato.go index fae19ee1c..cd89e631f 100644 --- a/server/item/poisonous_potato.go +++ b/server/item/poisonous_potato.go @@ -3,7 +3,7 @@ package item import ( "github.com/df-mc/dragonfly/server/entity/effect" "github.com/df-mc/dragonfly/server/world" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/item/rotten_flesh.go b/server/item/rotten_flesh.go index 3f1e5fd63..ff0579065 100644 --- a/server/item/rotten_flesh.go +++ b/server/item/rotten_flesh.go @@ -3,7 +3,7 @@ package item import ( "github.com/df-mc/dragonfly/server/entity/effect" "github.com/df-mc/dragonfly/server/world" - "math/rand" + "math/rand/v2" "time" ) diff --git a/server/player/conf.go b/server/player/conf.go index c895ae937..ed9c1f412 100644 --- a/server/player/conf.go +++ b/server/player/conf.go @@ -11,7 +11,7 @@ import ( "github.com/go-gl/mathgl/mgl64" "github.com/google/uuid" "golang.org/x/text/language" - "math/rand" + "math/rand/v2" "time" ) @@ -110,7 +110,7 @@ func fillDefaults(conf Config) Config { conf.Food, conf.Saturation = 20, 5 } if conf.EnchantmentSeed == 0 { - conf.EnchantmentSeed = rand.Int63() + conf.EnchantmentSeed = rand.Int64() } if conf.MaxAirSupply == 0 { conf.AirSupply, conf.MaxAirSupply = 300, 300 diff --git a/server/player/player.go b/server/player/player.go index 7d668bd9f..b258be365 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -3,7 +3,7 @@ package player import ( "fmt" "math" - "math/rand" + "math/rand/v2" "net" "slices" "strings" @@ -1425,9 +1425,22 @@ func (p *Player) UseItem() { p.updateState() return } - // The player is currently using the item held. This is a signal the - // item was consumed, so we release it. - p.ReleaseItem() + // The player is currently using the item held. This is a signal the item was consumed, so we + // consume it and start using it again. + useCtx, dur := p.useContext(), p.useDuration() + if dur < usable.ConsumeDuration() { + // The required duration for consuming this item was not met, so we don't consume it. + return + } + // Reset the duration for the next item to be consumed. + p.usingSince = time.Now() + ctx := event.C(p) + if p.Handler().HandleItemConsume(ctx, i); ctx.Cancelled() { + return + } + useCtx.CountSub, useCtx.NewItem = 1, usable.Consume(p.tx, p) + p.handleUseContext(useCtx) + p.tx.PlaySound(p.Position().Add(mgl64.Vec3{0, 1.5}), sound.Burp{}) } } @@ -1445,27 +1458,11 @@ func (p *Player) ReleaseItem() { useCtx, dur := p.useContext(), p.useDuration() i, _ := p.HeldItems() - switch it := i.Item().(type) { - case item.Releasable: - ctx := event.C(p) - if p.Handler().HandleItemRelease(ctx, i, dur); ctx.Cancelled() { - return - } - it.Release(p, p.tx, useCtx, dur) - case item.Consumable: - if dur < it.ConsumeDuration() { - // The required duration for consuming this item was not met, so we don't consume it. - return - } - ctx := event.C(p) - if p.Handler().HandleItemConsume(ctx, i); ctx.Cancelled() { - // Consuming was cancelled, but the client will continue consuming the next item. - p.usingSince = time.Now() - return - } - useCtx.CountSub, useCtx.NewItem = 1, it.Consume(p.tx, p) - p.tx.PlaySound(p.Position().Add(mgl64.Vec3{0, 1.5}), sound.Burp{}) + ctx := event.C(p) + if p.Handler().HandleItemRelease(ctx, i, dur); ctx.Cancelled() { + return } + i.Item().(item.Releasable).Release(p, p.tx, useCtx, dur) p.handleUseContext(useCtx) p.updateState() } @@ -1473,9 +1470,6 @@ func (p *Player) ReleaseItem() { // canRelease returns whether the player can release the item currently held in the main hand. func (p *Player) canRelease() bool { held, left := p.HeldItems() - if _, consumable := held.Item().(item.Consumable); consumable { - return true - } releasable, ok := held.Item().(item.Releasable) if !ok { return false @@ -2164,7 +2158,7 @@ func (p *Player) EnchantmentSeed() int64 { // ResetEnchantmentSeed resets the enchantment seed to a new random value. func (p *Player) ResetEnchantmentSeed() { - p.enchantSeed = rand.Int63() + p.enchantSeed = rand.Int64() } // AddExperience adds experience to the player. @@ -2257,7 +2251,7 @@ func (p *Player) mendItems(xp int) int { if length == 0 { return xp } - foundItem := mendingItems[rand.Intn(length)] + foundItem := mendingItems[rand.IntN(length)] repairAmount := math.Min(float64(foundItem.MaxDurability()-foundItem.Durability()), float64(xp*2)) repairedItem := foundItem.WithDurability(foundItem.Durability() + int(repairAmount)) if repairAmount >= 2 { @@ -2390,8 +2384,8 @@ func (p *Player) Tick(tx *world.Tx, current int64) { if p.prevWorld != tx.World() && p.prevWorld != nil { p.Handler().HandleChangeWorld(p, p.prevWorld, tx.World()) - p.prevWorld = tx.World() } + p.prevWorld = tx.World() if p.session() == session.Nop && !p.Immobile() { m := p.mc.TickMovement(p, p.Position(), p.Velocity(), p.Rotation(), p.tx) diff --git a/server/server.go b/server/server.go index a674b95a0..678aacebf 100644 --- a/server/server.go +++ b/server/server.go @@ -23,14 +23,15 @@ import ( "github.com/sandertv/gophertunnel/minecraft/protocol" "github.com/sandertv/gophertunnel/minecraft/protocol/login" "github.com/sandertv/gophertunnel/minecraft/protocol/packet" - "golang.org/x/exp/maps" "golang.org/x/text/language" "iter" + "maps" "os" "os/exec" "os/signal" "runtime" "runtime/debug" + "slices" "strings" "sync" "sync/atomic" @@ -252,7 +253,7 @@ func (srv *Server) Player(uuid uuid.UUID) (*world.EntityHandle, bool) { // found, the entity handle is returned and the bool returned holds a true // value. If not, the bool is false and the handle is nil func (srv *Server) PlayerByName(name string) (*world.EntityHandle, bool) { - if p, ok := sliceutil.SearchValue(maps.Values(srv.p), func(p *onlinePlayer) bool { + if p, ok := sliceutil.SearchValue(slices.Collect(maps.Values(srv.p)), func(p *onlinePlayer) bool { return p.name == name }); ok { return p.handle, true @@ -264,7 +265,7 @@ func (srv *Server) PlayerByName(name string) (*world.EntityHandle, bool) { // found, the entity handle is returned and the bool returned is true. If no // player with the XUID was found, nil and false are returned. func (srv *Server) PlayerByXUID(xuid string) (*world.EntityHandle, bool) { - if p, ok := sliceutil.SearchValue(maps.Values(srv.p), func(p *onlinePlayer) bool { + if p, ok := sliceutil.SearchValue(slices.Collect(maps.Values(srv.p)), func(p *onlinePlayer) bool { return p.xuid == xuid }); ok { return p.handle, true @@ -376,7 +377,7 @@ func (srv *Server) startListening() { // registered custom blocks. It allows block components to be created only once // at startup. func (srv *Server) makeBlockEntries() { - custom := maps.Values(world.CustomBlocks()) + custom := slices.Collect(maps.Values(world.CustomBlocks())) srv.customBlocks = make([]protocol.BlockEntry, len(custom)) for i, b := range custom { diff --git a/server/session/handler_anvil.go b/server/session/handler_anvil.go index 7ddce74fa..65f63fe1d 100644 --- a/server/session/handler_anvil.go +++ b/server/session/handler_anvil.go @@ -7,7 +7,7 @@ import ( "github.com/df-mc/dragonfly/server/world" "github.com/df-mc/dragonfly/server/world/sound" "github.com/sandertv/gophertunnel/minecraft/protocol" - "math/rand" + "math/rand/v2" ) const ( diff --git a/server/session/handler_enchanting.go b/server/session/handler_enchanting.go index 854075bf6..81db41bbb 100644 --- a/server/session/handler_enchanting.go +++ b/server/session/handler_enchanting.go @@ -10,7 +10,7 @@ import ( "github.com/sandertv/gophertunnel/minecraft/protocol" "github.com/sandertv/gophertunnel/minecraft/protocol/packet" "math" - "math/rand" + "math/rand/v2" "slices" ) @@ -119,7 +119,7 @@ func (s *Session) sendEnchantmentOptions(tx *world.Tx, c Controllable, pos cube. // to enchanting tables only. We also only need to set the middle index of Enchantments. The other two serve // an unknown purpose and can cause various unexpected issues. options = append(options, protocol.EnchantmentOption{ - Name: enchantNames[rand.Intn(len(enchantNames))], + Name: enchantNames[rand.IntN(len(enchantNames))], Cost: uint32(selectedCosts[i]), RecipeNetworkID: uint32(i), Enchantments: protocol.ItemEnchantments{ @@ -148,12 +148,13 @@ func (s *Session) determineAvailableEnchantments(tx *world.Tx, c Controllable, p // Search for bookshelves around the enchanting table. Bookshelves help boost the value of the enchantments that // are selected, resulting in enchantments that are rarer but also more expensive. - random := rand.New(rand.NewSource(c.EnchantmentSeed())) + seed := uint64(c.EnchantmentSeed()) + random := rand.New(rand.NewPCG(seed, seed)) bookshelves := searchBookshelves(tx, pos) value := enchantable.EnchantmentValue() // Calculate the base cost, used to calculate the upper, middle, and lower level costs. - baseCost := random.Intn(8) + 1 + (bookshelves >> 1) + random.Intn(bookshelves+1) + baseCost := random.IntN(8) + 1 + (bookshelves >> 1) + random.IntN(bookshelves+1) // Calculate the upper, middle, and lower level costs. upperLevelCost := max(baseCost/3, 1) @@ -185,7 +186,7 @@ func createEnchantments(random *rand.Rand, stack item.Stack, value, level int) [ randomBonus := (random.Float64() + random.Float64() - 1.0) * 0.15 // Calculate the enchantment cost and clamp it to ensure it is always at least one with triangular distribution. - cost := level + 1 + random.Intn(value/4+1) + random.Intn(value/4+1) + cost := level + 1 + random.IntN(value/4+1) + random.IntN(value/4+1) cost = clamp(int(math.Round(float64(cost)+float64(cost)*randomBonus)), 1, math.MaxInt32) // Books are applicable to all enchantments, so make sure we have a flag for them here. @@ -235,7 +236,7 @@ func createEnchantments(random *rand.Rand, stack item.Stack, value, level int) [ availableEnchants = slices.Delete(availableEnchants, ind, ind+1) // Based on the cost, select a random amount of additional enchantments. - for random.Intn(50) <= cost { + for random.IntN(50) <= cost { // Ensure that we don't have any conflicting enchantments. If so, remove them from the list of available // enchantments. lastEnchant := selectedEnchants[len(selectedEnchants)-1] @@ -306,7 +307,7 @@ func weightedRandomEnchantment(rs *rand.Rand, enchants []item.Enchantment) item. for _, e := range enchants { totalWeight += e.Type().Rarity().Weight() } - r := rs.Intn(totalWeight) + r := rs.IntN(totalWeight) for _, e := range enchants { r -= e.Type().Rarity().Weight() if r < 0 { diff --git a/server/session/handler_grindstone.go b/server/session/handler_grindstone.go index a89251294..ed19309dd 100644 --- a/server/session/handler_grindstone.go +++ b/server/session/handler_grindstone.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/df-mc/dragonfly/server/world" "math" - "math/rand" + "math/rand/v2" "github.com/df-mc/dragonfly/server/block" "github.com/df-mc/dragonfly/server/entity" @@ -94,7 +94,7 @@ func experienceFromEnchantments(stack item.Stack) int { } minExperience := int(math.Ceil(float64(totalCost) / 2)) - return minExperience + rand.Intn(minExperience) + return minExperience + rand.IntN(minExperience) } // stripPossibleEnchantments strips all enchantments possible, excluding curses. diff --git a/server/session/session_list.go b/server/session/session_list.go index 64b81f78f..8d16429ce 100644 --- a/server/session/session_list.go +++ b/server/session/session_list.go @@ -6,7 +6,7 @@ import ( "github.com/google/uuid" "github.com/sandertv/gophertunnel/minecraft/protocol" "github.com/sandertv/gophertunnel/minecraft/protocol/packet" - "golang.org/x/exp/slices" + "slices" "sync" ) diff --git a/server/session/world.go b/server/session/world.go index 87964c44b..48ef23761 100644 --- a/server/session/world.go +++ b/server/session/world.go @@ -3,7 +3,7 @@ package session import ( "github.com/df-mc/dragonfly/server/entity/effect" "image/color" - "math/rand" + "math/rand/v2" "strings" "time" @@ -1182,7 +1182,7 @@ func (s *Session) ViewWeather(raining, thunder bool) { EventType: packet.LevelEventStopRaining, } if raining { - pk.EventType, pk.EventData = packet.LevelEventStartRaining, int32(rand.Intn(50000)+10000) + pk.EventType, pk.EventData = packet.LevelEventStartRaining, int32(rand.IntN(50000)+10000) } s.writePacket(pk) @@ -1190,7 +1190,7 @@ func (s *Session) ViewWeather(raining, thunder bool) { EventType: packet.LevelEventStopThunderstorm, } if thunder { - pk.EventType, pk.EventData = packet.LevelEventStartThunderstorm, int32(rand.Intn(50000)+10000) + pk.EventType, pk.EventData = packet.LevelEventStartThunderstorm, int32(rand.IntN(50000)+10000) } s.writePacket(pk) } diff --git a/server/world/block.go b/server/world/block.go index 88c9328f2..7c3e4213a 100644 --- a/server/world/block.go +++ b/server/world/block.go @@ -10,7 +10,7 @@ import ( "image" "math" "math/bits" - "math/rand" + "math/rand/v2" "sort" ) @@ -240,7 +240,7 @@ func air() Block { // RandomTicker represents a block that executes an action when it is ticked randomly. Every 20th of a second, // one random block in each sub chunk are picked to receive a random tick. type RandomTicker interface { - // RandomTick handles a random tick of the block at the position passed. Additionally, a rand.Rand + // RandomTick handles a random tick of the block at the position passed. Additionally, a rand.RandSource // instance is passed which may be used to generate values randomly without locking. RandomTick(pos cube.Pos, tx *Tx, r *rand.Rand) } @@ -249,7 +249,7 @@ type RandomTicker interface { // when a block adjacent to it is broken. type ScheduledTicker interface { // ScheduledTick handles a scheduled tick initiated by an event in one of the neighbouring blocks, such as - // when a block is placed or broken. Additionally, a rand.Rand instance is passed which may be used to + // when a block is placed or broken. Additionally, a rand.RandSource instance is passed which may be used to // generate values randomly without locking. ScheduledTick(pos cube.Pos, tx *Tx, r *rand.Rand) } diff --git a/server/world/conf.go b/server/world/conf.go index 5f4a82f21..3514b3a5c 100644 --- a/server/world/conf.go +++ b/server/world/conf.go @@ -2,7 +2,7 @@ package world import ( "log/slog" - "math/rand" + "math/rand/v2" "time" ) @@ -46,8 +46,11 @@ type Config struct { RandomTickSpeed int // RandSource is the rand.Source used for generation of random numbers in a // World, such as when selecting blocks to tick or when deciding where to - // strike lightning. If set to nil, `rand.NewSource(time.Now().Unix())` will - // be used to generate a new source. + // strike lightning. If set to nil, RandSource defaults to a `rand.PCG` + // source seeded with `time.Now().UnixNano()`. PCG is significantly faster + // than `rand.ChaCha8` on 64-bit systems at the expense of poorer + // statistical distribution, which is acceptable here. + // See https://go.dev/blog/chacha8rand. RandSource rand.Source // Entities is an EntityRegistry with all Entity types registered that may // be added to the World. @@ -76,7 +79,8 @@ func (conf Config) New() *World { conf.RandomTickSpeed = 3 } if conf.RandSource == nil { - conf.RandSource = rand.NewSource(time.Now().Unix()) + t := uint64(time.Now().UnixNano()) + conf.RandSource = rand.NewPCG(t, t) } s := conf.Provider.Settings() w := &World{ diff --git a/server/world/entity.go b/server/world/entity.go index 4b5f61bfd..7beaf125e 100644 --- a/server/world/entity.go +++ b/server/world/entity.go @@ -5,8 +5,9 @@ import ( "github.com/df-mc/dragonfly/server/block/cube" "github.com/go-gl/mathgl/mgl64" "github.com/google/uuid" - "golang.org/x/exp/maps" "io" + "maps" + "slices" "sync" "sync/atomic" "time" @@ -400,7 +401,7 @@ func (reg EntityRegistry) Lookup(name string) (EntityType, bool) { // Types returns all EntityTypes passed upon construction of the EntityRegistry. func (reg EntityRegistry) Types() []EntityType { - return maps.Values(reg.ent) + return slices.Collect(maps.Values(reg.ent)) } func readVec3(x map[string]any, k string) mgl64.Vec3 { diff --git a/server/world/mcdb/db.go b/server/world/mcdb/db.go index 61abae57c..c0e368fdd 100644 --- a/server/world/mcdb/db.go +++ b/server/world/mcdb/db.go @@ -12,7 +12,7 @@ import ( "github.com/df-mc/goleveldb/leveldb" "github.com/google/uuid" "github.com/sandertv/gophertunnel/minecraft/nbt" - "math/rand" + "math/rand/v2" "os" "path/filepath" "slices" @@ -272,7 +272,7 @@ func (db *DB) entitiesOld(k dbKey) ([]chunk.Entity, error) { ent.ID, ok = ent.Data["UniqueID"].(int64) if !ok { db.conf.Log.Error("missing unique ID field, generating random", "data", fmt.Sprint(ent.Data)) - ent.ID = rand.Int63() + ent.ID = rand.Int64() } entities = append(entities, ent) } diff --git a/server/world/tick.go b/server/world/tick.go index c7d1772dd..9c025d807 100644 --- a/server/world/tick.go +++ b/server/world/tick.go @@ -3,8 +3,8 @@ package world import ( "github.com/df-mc/dragonfly/server/block/cube" "github.com/df-mc/dragonfly/server/internal/sliceutil" - "golang.org/x/exp/maps" - "math/rand" + "maps" + "math/rand/v2" "slices" "time" ) @@ -129,7 +129,7 @@ func (t ticker) tickBlocksRandomly(tx *Tx, loaders []*Loader, tick int64) { // No loaders in this chunk that are within the simulation distance, so proceed to the next. continue } - blockEntities = append(blockEntities, maps.Keys(c.BlockEntities)...) + blockEntities = append(blockEntities, slices.Collect(maps.Keys(c.BlockEntities))...) cx, cz := int(pos[0]<<4), int(pos[1]<<4) diff --git a/server/world/weather.go b/server/world/weather.go index 291fdb3e7..efcc7b18a 100644 --- a/server/world/weather.go +++ b/server/world/weather.go @@ -78,10 +78,10 @@ func (w weather) StopRaining() { defer w.w.set.Unlock() if w.w.set.Raining { - w.setRaining(false, time.Second*(time.Duration(w.w.r.Intn(8400)+600))) + w.setRaining(false, time.Second*(time.Duration(w.w.r.IntN(8400)+600))) if w.w.set.Thundering { // Also reset thunder if it was previously thundering. - w.setThunder(false, time.Second*(time.Duration(w.w.r.Intn(8400)+600))) + w.setThunder(false, time.Second*(time.Duration(w.w.r.IntN(8400)+600))) } } } @@ -103,7 +103,7 @@ func (w weather) StopThundering() { w.w.set.Lock() defer w.w.set.Unlock() if w.w.set.Thundering && w.w.set.Raining { - w.setThunder(false, time.Second*(time.Duration(w.w.r.Intn(8400)+600))) + w.setThunder(false, time.Second*(time.Duration(w.w.r.IntN(8400)+600))) } } @@ -120,9 +120,9 @@ func (w weather) advanceWeather() { // days) and when the rain is turned off it is reset to a value of // 12,000-179,999 ticks (0.5-7.5 game days). if w.w.set.Raining { - w.w.setRaining(false, time.Second*(time.Duration(w.w.r.Intn(8400)+600))) + w.w.setRaining(false, time.Second*(time.Duration(w.w.r.IntN(8400)+600))) } else { - w.w.setRaining(true, time.Second*time.Duration(w.w.r.Intn(600)+600)) + w.w.setRaining(true, time.Second*time.Duration(w.w.r.IntN(600)+600)) } } if w.w.set.ThunderTime <= 0 { @@ -132,9 +132,9 @@ func (w weather) advanceWeather() { // minutes), and when thunder is turned off the counter rests to // 12,000-179,999 ticks (0.5-7.5 days). if w.w.set.Thundering { - w.w.setThunder(false, time.Second*(time.Duration(w.w.r.Intn(8400)+600))) + w.w.setThunder(false, time.Second*(time.Duration(w.w.r.IntN(8400)+600))) } else { - w.w.setThunder(true, time.Second*time.Duration(w.w.r.Intn(620)+180)) + w.w.setThunder(true, time.Second*time.Duration(w.w.r.IntN(620)+180)) } } } @@ -171,7 +171,7 @@ func (w weather) tickLightning(tx *Tx) { for pos := range w.w.chunks { // Wiki: For each loaded chunk, every tick there is a 1⁄100,000 chance // of an attempted lightning strike during a thunderstorm - if w.w.r.Intn(100000) == 0 { + if w.w.r.IntN(100000) == 0 { positions = append(positions, pos) } } @@ -195,7 +195,7 @@ func (w weather) strikeLightning(tx *Tx, c ChunkPos) { // lightning and adjusts the position to any of the living entities found in or // above the position if any are found. func (w weather) lightningPosition(tx *Tx, c ChunkPos) mgl64.Vec3 { - v := w.w.r.Int31() + v := w.w.r.Int32() x, z := float64(c[0]<<4+(v&0xf)), float64(c[1]<<4+((v>>8)&0xf)) vec := w.adjustPositionToEntities(tx, mgl64.Vec3{x, float64(tx.HighestBlock(int(x), int(z)) + 1), z}) @@ -231,7 +231,7 @@ func (w weather) adjustPositionToEntities(tx *Tx, vec mgl64.Vec3) mgl64.Vec3 { // block and adjust the position of the lightning to it, so that the entity // is struck directly. if len(list) > 0 { - vec = list[w.w.r.Intn(len(list))] + vec = list[w.w.r.IntN(len(list))] } return vec } diff --git a/server/world/world.go b/server/world/world.go index 9c320839c..6e398cf03 100644 --- a/server/world/world.go +++ b/server/world/world.go @@ -5,7 +5,8 @@ import ( "errors" "fmt" "iter" - "math/rand" + "maps" + "math/rand/v2" "sync" "time" @@ -19,7 +20,6 @@ import ( "github.com/df-mc/dragonfly/server/world/chunk" "github.com/go-gl/mathgl/mgl64" "github.com/google/uuid" - "golang.org/x/exp/maps" "sync/atomic" )