

#include "destructor.h"

#include "material.h"
#include "block.h"
#include "tweak/tweak.h"
#include "cube.h"

#include "util.h"

#include "random.h"

namespace block {



bool Destructor::destruct(Block *b,C3f testpos,float size) {
	destroyed=0;
	Blockinfo3 bi;
	bi.block_=b;
	return destruct(bi,testpos,size);
}
bool dtest(Blockinfo3 bi,C3f collisionpos,float size) {
	// create bbox for block
	collisionpos.y-=Tweak::bomb_ycheat_f();
	C3f pos;
	Box3f box;
	pos=bi.pos_*Tweak::blockscale_f();
	pos-=size;
	box.add(pos);

	pos=bi.pos_;
	pos+=1*bi.scale_;
	pos*=Tweak::blockscale_f();
	pos+=size;
	box.add(pos);

	if (box.iswithin(collisionpos)) return true;
	return false;

}

bool Destructor::destruct(Blockinfo3 bi,C3f testpos,float size) {
	if (!dtest(bi,testpos,size)) {
		return false;
	}

	if (bi.level_<Tweak::bomb_splitlevel_i()+el7::Random::sget(3)) {
		bi.block_->split();
		bi.block_->dirty();
	}

	if (bi.block_->is_splitted()) {
		for (unsigned int i=0;i<8;i++) {
			destruct(bi.get_descend(i),testpos,size);
		}
		bi.block_->check_merge();
		return false;
	}
	E_Material mat;

	mat=bi.block_->get_material();
	if (mat==M_NONE) {
		return false;
	}
	if (!dtest(bi,testpos,size)) {
		return false;
	}

	float dist;
	C3f np;
	np=bi.pos_;
	np*=Tweak::blockscale_f();
	np.y+=Tweak::bomb_ycheat_f();
	dist=testpos.dist(np);

	if (dist>size*Tweak::bomb_boxsphere_fact_f()) return false;

	destroyed++;

	mat=M_NONE;
	if (dist>size*Tweak::bomb_bombedmat_fact_f()) {
		mat=M_BOMBEDWALL1;
		if (el7::Random::sget(4)!=0&&np.y<testpos.y) {
			float degree;
			degree=el7::destdegree(np,testpos);

			if (degree>270&&degree<360) {
				if (el7::Random::sboolean()) {
					mat=M_SLOPE_BOMBED1_1;
				} else {
					mat=M_SLOPE_BOMBED1_2;
				}
			}
			if (degree>0&&degree<90) {
				if (el7::Random::sboolean()) {
					mat=M_SLOPE_BOMBED2_1;
				} else {
					mat=M_SLOPE_BOMBED2_2;
				}
			}
			if (degree>90&&degree<180) {
				if (el7::Random::sboolean()) {
					mat=M_SLOPE_BOMBED3_1;
				} else {
					mat=M_SLOPE_BOMBED3_2;
				}
			}
			if (degree>180&&degree<270) {
				if (el7::Random::sboolean()) {
					mat=M_SLOPE_BOMBED4_1;
				} else {
					mat=M_SLOPE_BOMBED4_2;
				}
			}
		}
	}

	bi.block_->set_material(mat);
	bi.block_->dirty();
	return true;
}


} //namespace
