/*******************************************************************************
* Copyright (C) 2014 Travis Ralston (turt2live)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package com.turt2live.antishare.object.pattern;
import com.turt2live.antishare.object.ABlock;
import com.turt2live.antishare.object.AEntity;
import com.turt2live.antishare.object.attribute.Facing;
import java.util.ArrayList;
import java.util.List;
/**
* Represents the pattern required to create a wither boss.
*
* @author turt2live
*/
// TODO: Unit test
public abstract class WitherMobPattern implements BlockPattern, MobPattern {
protected enum WitherBlock {
SOUL_SAND,
SKULL
}
@Override
public boolean isCompleting(ABlock block) {
return getInvolvedBlocks(block).size() == 7; // 3 heads, 3 head mounts, and 1 foot
}
@Override
public List<ABlock> getInvolvedBlocks(ABlock block) {
if (block == null) throw new IllegalArgumentException();
List<ABlock> applicable = new ArrayList<>();
// Assuming the block is in a row of 3
ABlock n = block.getRelative(Facing.NORTH);
ABlock nn = n.getRelative(Facing.NORTH);
ABlock s = block.getRelative(Facing.SOUTH);
ABlock ss = block.getRelative(Facing.SOUTH);
ABlock e = block.getRelative(Facing.EAST);
ABlock ee = block.getRelative(Facing.EAST);
ABlock w = block.getRelative(Facing.WEST);
ABlock ww = block.getRelative(Facing.WEST);
ABlock[] row = new ABlock[3];
WitherBlock type = getType(block);
if (type != WitherBlock.SKULL) return applicable;
// Attempt to find the block in a row of 3
if (getType(n) == type && getType(s) == type) {
row[0] = n;
row[1] = block;
row[2] = s;
} else if (getType(w) == type && getType(e) == type) {
row[0] = e;
row[1] = block;
row[2] = w;
} else if (getType(n) == type && getType(nn) == type) {
row[0] = block;
row[1] = n;
row[2] = nn;
} else if (getType(s) == type && getType(ss) == type) {
row[0] = block;
row[1] = s;
row[2] = ss;
} else if (getType(e) == type && getType(ee) == type) {
row[0] = block;
row[1] = e;
row[2] = ee;
} else if (getType(w) == type && getType(ww) == type) {
row[0] = block;
row[1] = w;
row[2] = ww;
} else {
// No pattern match, not a row of three
return applicable;
}
// If we're here, we are in a row of three
ABlock[] otherRow = new ABlock[3];
WitherBlock opposite = WitherBlock.SOUL_SAND;
for (int i = 0; i < otherRow.length; i++) {
otherRow[i] = row[i].getRelative(Facing.DOWN);
if (getType(otherRow[i]) != opposite) return applicable; // No match
}
// Alright, we have 2 rows by now. Do we have a foot?
ABlock foot = (otherRow[1]).getRelative(Facing.DOWN);
if (getType(foot) == WitherBlock.SOUL_SAND) {
for (int i = 0; i < otherRow.length * 2; i++) {
applicable.add(i > 2 ? row[i - 3] : otherRow[i]);
}
applicable.add(foot);
}
return applicable;
}
@Override
public AEntity.RelevantEntityType getEntityType() {
return AEntity.RelevantEntityType.WITHER;
}
/**
* Gets the type of the passed block
*
* @param block the block, never null
*
* @return the block type, or null if no matches
*/
protected abstract WitherBlock getType(ABlock block);
}