1 /* 2 * Copyright (c) 2017-2019 sel-project 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in all 12 * copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 * 22 */ 23 /** 24 * Copyright: Copyright (c) 2017-2019 sel-project 25 * License: MIT 26 * Authors: Kripth 27 * Source: $(HTTP github.com/sel-project/selery/source/selery/item/placeable.d, selery/item/placeable.d) 28 */ 29 module selery.item.placeable; 30 31 import selery.about : block_t, item_t; 32 import selery.block.block : compareBlock; 33 import selery.block.blocks : Blocks; 34 import selery.item.item; 35 import selery.math.vector; 36 import selery.player.player : Player; 37 import selery.world.world : World; 38 39 static import sul.items; 40 41 class GenericPlaceableItem : Item { 42 43 //TODO ctor 44 45 public override pure nothrow @property @safe @nogc bool placeable() { 46 return true; 47 } 48 49 public override block_t place(World world, BlockPosition position, uint face) { 50 return this.block; 51 } 52 53 public abstract pure nothrow @property @safe @nogc block_t block(); 54 55 } 56 57 class PlaceableOnBlockItem : GenericPlaceableItem { 58 59 //TODO ctor 60 61 public override block_t place(World world, BlockPosition position, uint face) { 62 if(world[position - [0, 1, 0]] == this.supportBlocks) { 63 return super.place(world, position, face); 64 } else { 65 return 0; 66 } 67 } 68 69 public abstract pure nothrow @property @safe block_t[] supportBlocks(); 70 71 } 72 73 template PlaceableItem(sul.items.Item _data, block_t _block, E...) { 74 75 static if(E.length == 0) { 76 77 class PlaceableItem : GenericPlaceableItem { 78 79 public override pure nothrow @property @safe @nogc const sul.items.Item data() { 80 return _data; 81 } 82 83 public override pure nothrow @property @safe @nogc block_t block() { 84 return _block; 85 } 86 87 alias slot this; 88 89 } 90 91 } else static if(is(typeof(E[0]) == block_t[])) { 92 93 class PlaceableItem : PlaceableOnBlockItem { 94 95 public override pure nothrow @property @safe @nogc const sul.items.Item data() { 96 return _data; 97 } 98 99 public override pure nothrow @property @safe @nogc block_t block() { 100 return _block; 101 } 102 103 public override pure nothrow @property @safe block_t[] supportBlocks() { 104 return E[0]; 105 } 106 107 alias slot this; 108 109 } 110 111 } else { 112 113 class PlaceableItem : GenericPlaceableItem { 114 115 public override pure nothrow @property @safe @nogc const sul.items.Item data() { 116 return _data; 117 } 118 119 public override block_t place(World world, BlockPosition position, uint face) { 120 auto down = world[position - [0, 1, 0]]; 121 if(mixin((){ 122 import std..string : join; 123 string[] ret; 124 foreach(cmp ; E) { 125 ret ~= "down." ~ cmp; 126 } 127 return ret.join("&&"); 128 }())) { 129 return super.place(world, position, face); 130 } else { 131 return 0; 132 } 133 134 } 135 136 public override pure nothrow @property @safe @nogc block_t block() { 137 return _block; 138 } 139 140 } 141 142 } 143 144 } 145 146 alias PlaceableOnSolidItem(sul.items.Item _data, block_t _block) = PlaceableItem!(_data, _block, "fullUpperShape", "solid", "opacity==15"); 147 148 class WoodItem(sul.items.Item si, block_t[] blocks) : SimpleItem!(si) if(blocks.length == 4) { 149 150 alias sul = si; 151 152 public @safe this(E...)(E args) { 153 super(args); 154 } 155 156 public override pure nothrow @property @safe @nogc bool placeable() { 157 return true; 158 } 159 160 public override block_t place(World world, BlockPosition position, uint face) { 161 switch(face) { 162 case Face.EAST: 163 case Face.WEST: 164 return blocks[1]; 165 case Face.NORTH: 166 case Face.SOUTH: 167 return blocks[2]; 168 default: 169 return blocks[0]; 170 } 171 } 172 173 alias slot this; 174 175 } 176 177 class TorchItem(sul.items.Item si, block_t[] blocks) : SimpleItem!(si) if(blocks.length == 5) { 178 179 alias sul = si; 180 181 public @safe this(E...)(E args) { 182 super(args); 183 } 184 185 public override pure nothrow @property @safe @nogc bool placeable() { 186 return true; 187 } 188 189 public override block_t place(World world, BlockPosition position, uint face) { 190 //TODO place if valid surface 191 return blocks[0]; 192 } 193 194 alias slot this; 195 196 } 197 198 class BeansItem(sul.items.Item si, block_t[] blocks) : SimpleItem!(si) if(blocks.length == 4) { 199 200 alias sul = si; 201 202 public @safe this(E...)(E args) { 203 super(args); 204 } 205 206 public override pure nothrow @property @safe @nogc bool placeable() { 207 return true; 208 } 209 210 public override block_t place(World world, BlockPosition position, uint face) { 211 //TODO place if valid surface 212 return blocks[0]; 213 } 214 215 alias slot this; 216 217 } 218 219 class SlabItem(sul.items.Item si, block_t down, block_t up, block_t doubl) : SimpleItem!(si) { 220 221 alias sul = si; 222 223 public @safe this(E...)(E args) { 224 super(args); 225 } 226 227 public override pure nothrow @property @safe @nogc bool placeable() { 228 return true; 229 } 230 231 public override block_t place(World world, BlockPosition position, uint face) { 232 //TODO override onPlaced 233 return down; 234 } 235 236 alias slot this; 237 238 } 239 240 class StairsItem(sul.items.Item si, block_t[] orientations) : SimpleItem!(si) if(orientations.length == 8) { 241 242 // [east, west, south, north, upper east, upper west, upper south, upper north] 243 244 alias sul = si; 245 246 public @safe this(E...)(E args) { 247 super(args); 248 } 249 250 public override pure nothrow @property @safe @nogc bool placeable() { 251 return true; 252 } 253 254 public override block_t place(World world, BlockPosition position, uint face) { 255 //TODO override onPlaced 256 return orientations[0]; 257 } 258 259 alias slot this; 260 261 }