aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/multitileentity/multiblock/base/StackableController.java
blob: 51feb363dd29dcc4b5e428c165b4120eae12f275 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package gregtech.api.multitileentity.multiblock.base;

import net.minecraft.item.ItemStack;

import com.gtnewhorizon.structurelib.util.Vec3Impl;

import gregtech.api.logic.MuTEProcessingLogic;

public abstract class StackableController<C extends StackableController<C, P>, P extends MuTEProcessingLogic<P>>
    extends Controller<C, P> {

    protected static String STACKABLE_STOP = "STACKABLE_STOP";
    protected static String STACKABLE_MIDDLE = "STACKABLE_MIDDLE";
    protected static String STACKABLE_START = "STACKABLE_START";
    protected int stackCount = 0;

    /**
     * construct implementation for stackable multi-blocks
     */
    @Override
    public void construct(ItemStack trigger, boolean hintsOnly) {
        final int blueprintCount = (trigger.stackSize - 1) + getMinStacks();
        final int stackCount = Math.min(blueprintCount, getMaxStacks());

        buildState.startBuilding(getStartingStructureOffset());
        buildPiece(getStackableStart(), trigger, hintsOnly, buildState.getCurrentOffset());
        buildState.addOffset(getStartingStackOffset());

        for (int i = 0; i < stackCount; i++) {
            buildPiece(getStackableMiddle(i), trigger, hintsOnly, buildState.getCurrentOffset());
            buildState.addOffset(getPerStackOffset());
        }
        if (hasTop()) {
            buildState.addOffset(getAfterLastStackOffset());
            buildPiece(getStackableStop(), trigger, hintsOnly, buildState.stopBuilding());
        } else {
            buildState.stopBuilding();
        }
    }

    /**
     * Stackable
     *
     * @return The minimum number of stacks required for this multi-block to form
     */
    public abstract int getMinStacks();

    /**
     * Stackable
     *
     * @return The maximum number of stacks allowed for this multi-block to form
     */
    public abstract int getMaxStacks();

    /**
     * Stackable
     *
     * @return The starting offset for the first stack
     */
    public abstract Vec3Impl getStartingStackOffset();

    /**
     * Stackable
     *
     * @return The per stack offset
     */
    public abstract Vec3Impl getPerStackOffset();

    /**
     * Stackable
     *
     * @return Whether this structure has a Top/Cap. Defaults to true.
     */
    public boolean hasTop() {
        return true;
    }

    /**
     * Stackable
     *
     * @return Any offset needed after the last stack
     */
    public Vec3Impl getAfterLastStackOffset() {
        return new Vec3Impl(0, 0, 0);
    }

    /**
     * checkMachine implementation for stackable multi-blocks
     */
    @Override
    public boolean checkMachine() {
        stackCount = 0;

        buildState.startBuilding(getStartingStructureOffset());
        if (!checkPiece(getStackableStart(), buildState.getCurrentOffset())) return buildState.failBuilding();

        buildState.addOffset(getStartingStackOffset());

        for (int i = 0; i < getMaxStacks(); i++) {
            if (!checkPiece(getStackableMiddle(i), buildState.getCurrentOffset())) {
                break;
            }

            buildState.addOffset(getPerStackOffset());
            stackCount++;

        }
        if (stackCount < getMinStacks()) return buildState.failBuilding();

        buildState.addOffset(getAfterLastStackOffset());
        if (!checkPiece(getStackableStop(), buildState.stopBuilding())) {
            return buildState.failBuilding();
        }
        return super.checkMachine();
    }

    protected String getStackableStop() {
        return STACKABLE_STOP;
    }

    protected String getStackableMiddle(int stackIndex) {
        return STACKABLE_MIDDLE;
    }

    protected String getStackableStart() {
        return STACKABLE_START;
    }
}