github.com/df-mc/dragonfly@v0.9.13/server/world/dimension.go (about)

     1  package world
     2  
     3  import (
     4  	"github.com/df-mc/dragonfly/server/block/cube"
     5  	"math"
     6  	"time"
     7  )
     8  
     9  var (
    10  	// Overworld is the Dimension implementation of a normal overworld. It has a
    11  	// blue sky under normal circumstances and has a sun, clouds, stars and a
    12  	// moon. Overworld has a building range of [-64, 320).
    13  	Overworld overworld
    14  	// Nether is a Dimension implementation with a lower base light level and a
    15  	// darker sky without sun/moon. It has a building range of [0, 128).
    16  	Nether nether
    17  	// End is a Dimension implementation with a dark sky. It has a building
    18  	// range of [0, 256).
    19  	End end
    20  )
    21  
    22  var dimensionReg = newDimensionRegistry(map[int]Dimension{
    23  	0: Overworld,
    24  	1: Nether,
    25  	2: End,
    26  })
    27  
    28  // DimensionByID looks up a Dimension for the ID passed, returning Overworld
    29  // for 0, Nether for 1 and End for 2. If the ID is unknown, the bool returned
    30  // is false. In this case the Dimension returned is Overworld.
    31  func DimensionByID(id int) (Dimension, bool) {
    32  	return dimensionReg.Lookup(id)
    33  }
    34  
    35  // DimensionID looks up the ID that a Dimension was registered with. If not
    36  // found, false is returned.
    37  func DimensionID(dim Dimension) (int, bool) {
    38  	return dimensionReg.LookupID(dim)
    39  }
    40  
    41  type dimensionRegistry struct {
    42  	dimensions map[int]Dimension
    43  	ids        map[Dimension]int
    44  }
    45  
    46  // newDimensionRegistry returns an initialised dimensionRegistry.
    47  func newDimensionRegistry(dim map[int]Dimension) *dimensionRegistry {
    48  	ids := make(map[Dimension]int, len(dim))
    49  	for k, v := range dim {
    50  		ids[v] = k
    51  	}
    52  	return &dimensionRegistry{dimensions: dim, ids: ids}
    53  }
    54  
    55  // Lookup looks up a Dimension for the ID passed, returning Overworld for 0,
    56  // Nether for 1 and End for 2. If the ID is unknown, the bool returned is
    57  // false. In this case the Dimension returned is Overworld.
    58  func (reg *dimensionRegistry) Lookup(id int) (Dimension, bool) {
    59  	dim, ok := reg.dimensions[id]
    60  	if !ok {
    61  		dim = Overworld
    62  	}
    63  	return dim, ok
    64  }
    65  
    66  // LookupID looks up the ID that a Dimension was registered with. If not found,
    67  // false is returned.
    68  func (reg *dimensionRegistry) LookupID(dim Dimension) (int, bool) {
    69  	id, ok := reg.ids[dim]
    70  	return id, ok
    71  }
    72  
    73  type (
    74  	// Dimension is a dimension of a World. It influences a variety of
    75  	// properties of a World such as the building range, the sky colour and the
    76  	// behaviour of liquid blocks.
    77  	Dimension interface {
    78  		// Range returns the lowest and highest valid Y coordinates of a block
    79  		// in the Dimension.
    80  		Range() cube.Range
    81  		WaterEvaporates() bool
    82  		LavaSpreadDuration() time.Duration
    83  		WeatherCycle() bool
    84  		TimeCycle() bool
    85  	}
    86  	overworld struct{}
    87  	nether    struct{}
    88  	end       struct{}
    89  	nopDim    struct{}
    90  )
    91  
    92  func (overworld) Range() cube.Range                 { return cube.Range{-64, 319} }
    93  func (overworld) WaterEvaporates() bool             { return false }
    94  func (overworld) LavaSpreadDuration() time.Duration { return time.Second * 3 / 2 }
    95  func (overworld) WeatherCycle() bool                { return true }
    96  func (overworld) TimeCycle() bool                   { return true }
    97  func (overworld) String() string                    { return "Overworld" }
    98  
    99  func (nether) Range() cube.Range                 { return cube.Range{0, 127} }
   100  func (nether) WaterEvaporates() bool             { return true }
   101  func (nether) LavaSpreadDuration() time.Duration { return time.Second / 4 }
   102  func (nether) WeatherCycle() bool                { return false }
   103  func (nether) TimeCycle() bool                   { return false }
   104  func (nether) String() string                    { return "Nether" }
   105  
   106  func (end) Range() cube.Range                 { return cube.Range{0, 255} }
   107  func (end) WaterEvaporates() bool             { return false }
   108  func (end) LavaSpreadDuration() time.Duration { return time.Second * 3 / 2 }
   109  func (end) WeatherCycle() bool                { return false }
   110  func (end) TimeCycle() bool                   { return false }
   111  func (end) String() string                    { return "End" }
   112  
   113  func (nopDim) Range() cube.Range                 { return cube.Range{} }
   114  func (nopDim) WaterEvaporates() bool             { return false }
   115  func (nopDim) LavaSpreadDuration() time.Duration { return math.MaxInt64 }
   116  func (nopDim) WeatherCycle() bool                { return false }
   117  func (nopDim) TimeCycle() bool                   { return false }
   118  func (nopDim) String() string                    { return "" }