//Kai/Zen 2D Game Engine: Returns the list of blocks which are affected by the given explosion
char* cMapGetExplosionBlocks(uintptr_t cMapAddress, double bombX, double bombY, double bombMass, long long cClass, long long iTypeRange, long long fTypeRange, bool singleBomb, double bombEffectRadiusMultiplier)
{
ContentMap *cMap = (ContentMap*)(cMapAddress);
int hB = (int)(ceil(cMap->halfBlockSize));
int mX = (int)(bombX * cMap->invBlockSize);
int mY = (int)(bombY * cMap->invBlockSize);
int bX = (mX * cMap->blockSize) + hB;
int bY = (mY * cMap->blockSize) + hB;
int numberOfBombs = 1;
if (!singleBomb) {
numberOfBombs = cMapContainsType(cMapAddress, mX, mY, cClass, iTypeRange, fTypeRange);
if (numberOfBombs == 0) {
return "";
};
}
double cR = cbrt(bombMass * 0.375 * numberOfBombs);
double pR = (cR * cMap->blockSize) + cMap->halfBlockSize;
double rS = pR * pR;
double aS = rS * bombEffectRadiusMultiplier;
int sX, sY, dX, dY;
std::stringstream ss1;
std::stringstream ss2;
for (int pX = (int)(bX - pR); pX <= (bX + hB); pX += cMap->blockSize) {
mX = (int)(pX * cMap->invBlockSize);
dX = ((mX * cMap->blockSize) + hB) - bX;
for (int pY = (int)(bY - pR); pY <= (bY + hB); pY += cMap->blockSize) {
mY = (int)(pY * cMap->invBlockSize);
dY = ((mY * cMap->blockSize) + hB) - bY;
//Create list of affected blocks
int distSq = (dX * dX) + (dY * dY);
if (distSq <= aS) {
//Create list of exploding blocks
if (distSq <= rS) {
sX = (int)((bX - dX) * cMap->invBlockSize);
sY = (int)((bY - dY) * cMap->invBlockSize);
if (mX >= 0 && mX < cMap->sizeX && mY >=0 && mY < cMap->sizeY) {
ss1 << "," << std::to_string(mX) << "," << std::to_string(mY);
}
if (sX != mX && sY != mY && sX >= 0 && sX < cMap->sizeX && sY >= 0 && sY < cMap->sizeY) {
ss1 << "," << std::to_string(sX) << "," << std::to_string(mY);
ss1 << "," << std::to_string(mX) << "," << std::to_string(sY);
ss1 << "," << std::to_string(sX) << "," << std::to_string(sY);
}
else {
if (sX != mX && sX >= 0 && sX < cMap->sizeX && mY >= 0 && mY < cMap->sizeY) {
ss1 << "," << std::to_string(sX) << "," << std::to_string(mY);
}
if (sY != mY && mX >= 0 && mX < cMap->sizeX && sY >= 0 && sY < cMap->sizeY) {
ss1 << "," << std::to_string(mX) << "," << std::to_string(sY);
}
}
}
//End of List Creation
sX = (int)((bX - dX) * cMap->invBlockSize);
sY = (int)((bY - dY) * cMap->invBlockSize);
if (mX >= 0 && mX < cMap->sizeX && mY >= 0 && mY < cMap->sizeY) {
ss2 << "," << std::to_string(mX) << "," << std::to_string(mY);
}
if (sX != mX && sY != mY && sX >= 0 && sX < cMap->sizeX && sY >= 0 && sY < cMap->sizeY) {
ss2 << "," << std::to_string(sX) << "," << std::to_string(mY);
ss2 << "," << std::to_string(mX) << "," << std::to_string(sY);
ss2 << "," << std::to_string(sX) << "," << std::to_string(sY);
}
else {
if (sX != mX && sX >= 0 && sX < cMap->sizeX && mY >= 0 && mY < cMap->sizeY) {
ss2 << "," << std::to_string(sX) << "," << std::to_string(mY);
}
if (sY != mY && mX >= 0 && mX < cMap->sizeX && sY >= 0 && sY < cMap->sizeY) {
ss2 << "," << std::to_string(mX) << "," << std::to_string(sY);
}
}
}
//End of List Creation
}
}
std::string output2 = ss2.str();
char* result2 = (char*)output2.c_str();
size_t allocSize2 = sizeof(result2) * output2.length();
if (allocSize2 > 0) {
cMap->lastExplosionRadius = (int)pR;
if (strlen(cMap->outputBufferB) < allocSize2) {
cMap->outputBufferB = (char*)realloc(cMap->outputBufferB, allocSize2);
}
strcpy(cMap->outputBufferB, result2);
}
std::string output1 = ss1.str();
char* result1 = (char*)output1.c_str();
size_t allocSize1 = sizeof(result1) * output1.length();
if (allocSize1 > 0) {
if (strlen(cMap->outputBufferA) < allocSize2) {
cMap->outputBufferA = (char*)realloc(cMap->outputBufferA, allocSize1);
}
strcpy(cMap->outputBufferA, result1);
return cMap->outputBufferA;
}
else {
return "";
}
}