1 /*
2  * Copyright (c) 2017-2018 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: 2017-2018 sel-project
25  * License: MIT
26  * Authors: Kripth
27  * Source: $(HTTP github.com/sel-project/selery/source/selery/block/fluid.d, selery/block/fluid.d)
28  */
29 module selery.block.fluid;
30 
31 import selery.about : block_t, item_t;
32 import selery.block.block;
33 import selery.math.vector : BlockPosition;
34 
35 static import sul.blocks;
36 
37 //TODO
38 class FluidBlock : Block {
39 
40 	public this(sul.blocks.Block data) {
41 		super(data);
42 	}
43 
44 	public final override pure nothrow @property @safe @nogc bool fluid() {
45 		return true;
46 	}
47 
48 	/*public override void onUpdate(Update update) {
49 		static if(curr_level <= max_level) {
50 			this.scheduleUpdate();
51 		}
52 	}
53 
54 	public override void onScheduledUpdate() {
55 		this.has_scheduled = false;
56 		static if(curr_level > 0) {
57 			//check if the source has been removed
58 			if((*this.source) is null || ((*this.source) != name && (*this.source).metas.pe != curr_level - per_level)) {
59 				this = Blocks.AIR;
60 				return;
61 			}
62 		}
63 		//check bottom
64 		bool flowed;
65 		if(this.canFlow(this.down)) {
66 			//prevent replacing a source
67 			if(this.down !is null && this.down.name == name && this.down.metas.pe == 0) return;
68 			static if(curr_level != 0) {
69 				flowed = true;
70 			}
71 			if(this.down !is null) this.world.drops(this.down);
72 			this.world[this.position.substract(0, 1, 0)] = new FluidBlock!(name, ids, per_level, max_level, per_level, time)(this.world.pointer(this.position));
73 		}
74 		static if(curr_level + per_level <= max_level) {
75 			if(!flowed) {
76 				foreach(int[2] c ; this.bestWays) {
77 					BlockPosition position = this.position.add(c[0], 0, c[1]);
78 					Block b = this.world[position];
79 					if(this.canFlow!true(b)) {
80 						if(b !is null) this.world.drops(b);
81 						this.world[position] = new FluidBlock!(name, ids, curr_level + per_level, max_level, per_level, time)(this.world.pointer(this.position));
82 					}
83 				}
84 			}
85 		}
86 	}
87 
88 	private bool canFlow(bool checkname=false)(Block block) {
89 		static if(checkname) {
90 			return block is null || (block.replaceable || block.directBlastResistance == 0) && (block.name != name || block.metas.pe > curr_level + per_level);
91 		} else {
92 			return block is null || block.replaceable || block.directBlastResistance == 0;
93 		}
94 	}
95 
96 	private @property int[][] bestWays() {
97 		int[][] ret;
98 		foreach(int[] pos ; [[-1, 0], [1, 0], [0, -1], [0, 1]]) {
99 			Block b = this.world[this.position.add(pos[0], 0, pos[1])];
100 			if(b is null || b.directBlastResistance == 0) {
101 				b = this.world[this.position.add(pos[0], -1, pos[1])];
102 				if(b is null || b.directBlastResistance == 0) {
103 					ret ~= pos;
104 				}
105 			}
106 		}
107 		return ret.length == 0 ? [[-1, 0], [1, 0], [0, -1], [0, 1]] : ret;
108 	}
109 
110 	private void scheduleUpdate() {
111 		if(!this.has_scheduled) {
112 			this.has_scheduled = true;
113 			this.world.scheduleBlockUpdate(this, time);
114 		}
115 	}*/
116 
117 	public override pure nothrow @property @safe @nogc float fallDamageModifier() {
118 		return 0;
119 	}
120 
121 }