1 package minecraft 2 3 import ( 4 "strconv" 5 6 "vimagination.zapto.org/minecraft/nbt" 7 ) 8 9 // Tick is a type that represents a scheduled tick 10 type Tick struct { 11 I, T, P int32 12 } 13 14 // Block is a type that represents the full information for a block, id, data, 15 // metadata and scheduled tick data 16 type Block struct { 17 ID uint16 18 Data uint8 19 metadata nbt.Compound 20 ticks []Tick 21 } 22 23 // Equal is an implementation of the equaler.Equaler interface 24 func (b Block) Equal(e interface{}) bool { 25 c, ok := e.(Block) 26 if !ok { 27 d, ok := e.(*Block) 28 if !ok { 29 return false 30 } 31 c = *d 32 } 33 return b.EqualBlock(c) 34 } 35 36 // EqualBlock checks for equality between the two blocks 37 func (b Block) EqualBlock(c Block) bool { 38 if b.ID == c.ID && b.Data == c.Data && len(b.metadata) == len(c.metadata) && len(b.ticks) == len(c.ticks) { 39 for _, bT := range b.ticks { 40 found := false 41 for _, cT := range c.ticks { 42 if bT.I == cT.I && bT.T == cT.T && bT.P == cT.P { 43 found = true 44 break 45 } 46 } 47 if !found { 48 return false 49 } 50 } 51 for _, v := range b.metadata { 52 name := v.Name() 53 found := false 54 for _, w := range c.metadata { 55 if w.Name() == name { 56 if !v.Equal(w) { 57 return false 58 } 59 found = true 60 break 61 } 62 } 63 if !found { 64 return false 65 } 66 } 67 return true 68 } 69 return false 70 } 71 72 // Opacity returns how much light is blocked by this block. 73 func (b Block) Opacity() uint8 { 74 if b.ID == 8 || b.ID == 9 { 75 return 3 76 } 77 for i := 0; i < len(TransparentBlocks); i++ { 78 if TransparentBlocks[i] == b.ID { 79 return 1 80 } 81 } 82 return 15 83 } 84 85 // Light returns how much light is generated by this block. 86 func (b Block) Light() uint8 { 87 if l, ok := LightBlocks[b.ID]; ok { 88 return l 89 } 90 return 0 91 } 92 93 // IsLiquid returns true if the block id matches a liquid 94 func (b Block) IsLiquid() bool { 95 return b.ID == 8 || b.ID == 9 || b.ID == 10 || b.ID == 11 96 } 97 98 // HasMetadata returns true the the block contains extended metadata 99 func (b Block) HasMetadata() bool { 100 return len(b.metadata) > 0 101 } 102 103 // GetMetadata returns a copy of the metadata for this block, or nil is it has 104 // none 105 func (b Block) GetMetadata() nbt.Compound { 106 if b.metadata == nil { 107 return nil 108 } 109 return b.metadata.Copy().(nbt.Compound) 110 } 111 112 // SetMetadata sets the blocks metadata to a copy of the given metadata 113 func (b *Block) SetMetadata(data nbt.Compound) { 114 metadata := make(nbt.Compound, 0) 115 for i := 0; i < len(data); i++ { 116 name := data[i].Name() 117 if name == "x" || name == "y" || name == "z" { 118 continue 119 } else if data[i].TagID() == nbt.TagEnd { 120 break 121 } 122 metadata = append(metadata, data[i].Copy()) 123 } 124 if len(metadata) > 0 { 125 b.metadata = metadata 126 } else { 127 b.metadata = nil 128 } 129 } 130 131 // HasTicks returns true if the block has any scheduled ticks 132 func (b Block) HasTicks() bool { 133 return len(b.ticks) > 0 134 } 135 136 // GetTicks returns all of the scheduled ticks for a block 137 func (b Block) GetTicks() []Tick { 138 t := make([]Tick, len(b.ticks)) 139 copy(t, b.ticks) 140 return t 141 } 142 143 // AddTicks adds one or more scheduled ticks to the block 144 func (b *Block) AddTicks(t ...Tick) { 145 b.ticks = append(b.ticks, t...) 146 } 147 148 // SetTicks sets the scheduled ticks for the block, replacing any existing ones 149 func (b *Block) SetTicks(t []Tick) { 150 b.ticks = make([]Tick, len(t)) 151 copy(b.ticks, t) 152 } 153 154 func (b Block) String() string { 155 toRet := "Block ID: " + strconv.FormatUint(uint64(b.ID), 10) + "\nData: " + strconv.FormatUint(uint64(b.Data), 10) + "\n" 156 if b.metadata != nil && len(b.metadata) != 0 { 157 toRet += "Metadata: " + b.metadata.String() 158 } 159 for n, tick := range b.ticks { 160 toRet += " Tick: " + strconv.FormatInt(int64(n+1), 10) + ", i: " + strconv.FormatInt(int64(tick.I), 10) + ", t: " + strconv.FormatInt(int64(tick.T), 10) + ", p: " + strconv.FormatInt(int64(tick.I), 10) 161 } 162 return toRet 163 } 164