Author Topic: Prevent specific bricks from being chainkilled  (Read 1089 times)

Because Ghost's Terrain Generator is privatized (sigh), I can't use it for reference, tracing isn't giving enough back either.

I would assume
Code: [Select]
function fxDTSBrick::killBrick(%this) {
if(!%this.isMineable) {
parent::killBrick(%this);
}
}
would be enough to prevent specific bricks from being killed, but in things like the wand, destructo wand, and undoing bricks, the bricks floating underneath it are still killed.

What's the correct way to go about preventing specific floating bricks from being killed?

I believe there's an .isGrounded variable on bricks which is normally assigned when you plant it on the ground, not sure on the name though. Look up that add-on which let you place modter bricks in the air, pretty sure that used it.

If you set isBaseplate to true when you create a brick, the engine assumes it to be supported by the ground/interior/whatever.

That way you can build floating cubes and have ctrl z working correctly for bricks on top, etc...

The generator will be released publicly as soon as it's finished. =) If Zeblote's suggestion works, that would probably be the best option. For PTG however, I had to package functions for the hammer, the wand, the destructo wand and for killBrick. You could probably do something like this (hasn't been tested):

Code: [Select]
//When using the hammer, wand or destructo wand
function hammerimage::onHitObject(%this,%obj,%slot,%col,%d,%e,%f)
{
%parent = parent::onHitObject(%this,%obj,%slot,%col,%d,%e,%f);

if(%col.getClassName() !$= "fxDTSBrick")
return %parent;
else
{
if(%col.hasPathToGround() || (isObject(%col.getUpBrick(0)) && isObject(%col.getDownBrick(0))))
return parent::onHitObject(%this,%obj,%slot,%col,%d,%e,%f);
else if(!%col.removing)
{
//custom brick removal (also can just use "%col.delete();")
ServerPlay3D(brickBreakSound,%col.getPosition());
%col.fakeKillBrick(getRandom(-10,10) SPC getRandom(-10,10) SPC getRandom(0,10),3); //"0 0 8"
%col.removing = true; //prevents function from being spammed while brick is being removed
%col.schedule(500,delete);

return;
}
}

return %parent;
}
function wandimage::onHitObject(%this,%obj,%slot,%col,%d,%e,%f)
{
%parent = parent::onHitObject(%this,%obj,%slot,%col,%d,%e,%f);

if(%col.getClassName() !$= "fxDTSBrick")
return %parent;
else
{
if(!%col.willCauseChainKill() || %col.hasPathToGround())
return parent::onHitObject(%this,%obj,%slot,%col,%d,%e,%f);
else if(!%col.removing)
{
//custom brick removal (also can just use "%col.delete();")
ServerPlay3D(brickBreakSound,%col.getPosition());
%col.fakeKillBrick(getRandom(-10,10) SPC getRandom(-10,10) SPC getRandom(0,10),3); //"0 0 8"
%col.removing = true; //prevents function from being spammed while brick is being removed
%col.schedule(500,delete);

return;
}
}

return %parent;
}
function adminwandimage::onHitObject(%this,%obj,%slot,%col,%d,%e,%f)
{
%parent = parent::onHitObject(%this,%obj,%slot,%col,%d,%e,%f);

if(%col.getClassName() !$= "fxDTSBrick")
return %parent;
else
{
if(!%col.willCauseChainKill() || %col.hasPathToGround())
return parent::onHitObject(%this,%obj,%slot,%col,%d,%e,%f);
else if(!%col.removing)
{
//custom brick removal (also can just use "%col.delete();")
ServerPlay3D(brickBreakSound,%col.getPosition());
%col.fakeKillBrick(getRandom(-10,10) SPC getRandom(-10,10) SPC getRandom(0,10),3); //"0 0 8"
%col.removing = true; //prevents function from being spammed while brick is being removed
%col.schedule(500,delete);

return;
}
}

return %parent;
}

//When undoing bricks
function fxDTSBrick::killBrick(%this)
{
if(%this.willCauseChainKill() && !%this.hasPathToGround() && !%this.removing)
{
//custom brick removal (also can just use "%this.delete();")
ServerPlay3D(brickBreakSound,%this.getPosition());
%this.fakeKillBrick(getRandom(-10,10) SPC getRandom(-10,10) SPC getRandom(0,10),3); //"0 0 8"
%this.removing = true; //prevents function from being spammed while brick is being removed
%this.schedule(500,delete);

return;
}

parent::killBrick(%this);
}

The modified functions will check to see if a brick will cause a chainKill for the wand and destructo wand, and will delete the brick instead after playing the fakeKill animation. For the hammer, it'll also delete the brick with the fakeKill animation, but only if either the top, bottom or both sides of the brick are exposed; it's not a perfect solution, but it works fairly well.

If you wanted to still cause a chainKill, without destroying the supporting floating brick, that would be slightly more complicated. You would have to cycle through each above brick and delete it manually using the .getUpBrick(#) method (you might also have to cycle through down bricks as well, depending).
« Last Edit: November 21, 2015, 01:29:08 PM by [GSF]Ghost »

Note that willCauseChainKill() can cause extreme lag depending on how your bricks are stacked, much more than killBrick() itself would. I wouldn't call that if there's a way without.

I believe there's an .isGrounded variable on bricks which is normally assigned when you plant it on the ground, not sure on the name though. Look up that add-on which let you place modter bricks in the air, pretty sure that used it.
If you set isBaseplate to true when you create a brick, the engine assumes it to be supported by the ground/interior/whatever.

That way you can build floating cubes and have ctrl z working correctly for bricks on top, etc...
both of these still causes a chain to be killed :(

Code: [Select]
%brick = new fxDTSBrick(_TerrainBrick) {
angleID = 0;
client = -1;
colorFxID = 0;
colorID = getField($Terrain::Color[%color], 0);
dataBlock = %dataBlock;
isBasePlate = 1;
isGrounded = 1;
isPlanted = 1;
position = %x SPC %y SPC %z;
printID = 0;
rotation = "0 0 0 0";
scale = "1 1 1";
shapeFxID = 0;
stackBL_ID = 888888;
isMineable = 1;
health = 15;
maxHealth = 15;
};
%brick.plant();
%brick.setTrusted(1);

BrickGroup_888888.add(%brick);

Wait, which brick are you killing? If you destroy the one with isBaseplate set, bricks on top of it that don't have it set will die aswell.

just a 1x1 I manually planted on top, i'd assume the terrain underneath would be fine, but it's killed along with it

tried to experiment with getDownBrick and getUpBrick to no avail
Code: [Select]
function fxDTSBrick::getDownBrick(%this, %index) {
%brick = parent::getDownBrick(%this, %index);
if(%brick.isMineable) {
return 0;
}
return %brick;
}

function fxDTSBrick::getUpBrick(%this, %index) {
%brick = parent::getUpBrick(%this, %index);
if(%brick.isMineable) {
return 0;
}
return %brick;
}

EDIT: The only solution so far that has worked to an extent (minus the snippet of code from Ghost), has been to recreate the terrain bricks that were destroyed.
Obviously this is bad as anyone could exploit that to cause ghosting. so
« Last Edit: November 23, 2015, 05:35:52 PM by TheBlackParrot »

Those are engine functions, you can't change them. The same goes for chain killing

Those are engine functions, you can't change them. The same goes for chain killing
well stuff
I might just shelve this freebuild project then, it's not worth the issues i can't fix well enough to remain stable