Author Topic: Planting bricks in the 4x4 grid  (Read 1282 times)

Can you help me in my Advanced Mining RP?

I want to implement dirt/cement planting, but I want it like how Destiny does it in Blockcraft, it stays on the 4x4 grid. I want to do this using an item/tool, which when it fires, it places a dirt or cement or any 4x4 brick.

How will I be sure it stays on 4x4 grid? I'm sure there's math into it, but I don't know how.

My dirt placing function is:

Code: [Select]
function AdvDig_PlacePlayerBlock(%pos)
%pos is the position where to plant the block. I want to make sure it always stays on the 4x4 grid.

Code: [Select]
function YourDirtWeaponProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
if(%col.getDatablock().brickSizeX == 4 && %col.getDatablock().brickSizeY == 4)
{
%pos = getWords(%col.getTransform(),0,2);
switch$(%normal)
{
case "0 0 1":
%pos = vectorAdd(%pos,"0 0 10");
case "0 0 -1":
%pos = vectorAdd(%pos,"0 0 -10");
case "0 1 0":
%pos = vectorAdd(%pos,"0 4 0");
case "0 -1 0":
%pos = vectorAdd(%pos,"0 -4 0");
case "1 0 0":
%pos = vectorAdd(%pos,"4 0 0");
case "-1 0 0":
%pos = vectorAdd(%pos,"-4 0 0");
}
%brick = new fxDTSBrick()
    {
client = $Dig_host;
datablock = "brick4xCubeData";
position = %pos;
colorID = 8;
colorfxID = 0;
shapefxID = 0;
isPlanted = 1;
stackBL_ID = $Dig_host_id;
type = ""; //dunno what this is for
isMineable = 1;
health = 10;
};
if(isObject(%brick))
{
$Dig_host_brickgroup.add(%brick);
$Dig_placedDirt[%pos] = 1;
$server::BrickCount++;
//also negate dirt here I guess?
}
}
}
(sorry I didn't respond to your pm, I forgot about it)


it overlaps bricks lol:


Code: [Select]
function YourDirtWeaponProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
if(%col.getDatablock().brickSizeX == 4 && %col.getDatablock().brickSizeY == 4)
{
%pos = getWords(%col.getTransform(),0,2);
switch$(%normal)
{
case "0 0 1":
%pos = vectorAdd(%pos,"0 0 2");
case "0 0 -1":
%pos = vectorAdd(%pos,"0 0 -2");
case "0 1 0":
%pos = vectorAdd(%pos,"0 2 0");
case "0 -1 0":
%pos = vectorAdd(%pos,"0 -2 0");
case "1 0 0":
%pos = vectorAdd(%pos,"2 0 0");
case "-1 0 0":
%pos = vectorAdd(%pos,"-2 0 0");
}
%brick = new fxDTSBrick()
    {
client = $Dig_host;
datablock = "brick4xCubeData";
position = %pos;
colorID = 8;
colorfxID = 0;
shapefxID = 0;
isPlanted = 1;
stackBL_ID = $Dig_host_id;
type = ""; //dunno what this is for
isMineable = 1;
health = 10;
};
if(isObject(%brick))
{
$Dig_host_brickgroup.add(%brick);
$Dig_placedDirt[%pos] = 1;
$server::BrickCount++;
//also negate dirt here I guess?
}
}
}
(sorry I didn't respond to your pm, I forgot about it)



It does more weirdness now D:

The code:

Code: [Select]
datablock ParticleData(DirtParticleC)
{
dragCoefficient      = 0.0;
gravityCoefficient   = -1;
inheritedVelFactor   = 0.0;
constantAcceleration = 0.0;
lifetimeMS           = 100;
lifetimeVarianceMS   = 75;
textureName          = "base/data/particles/cloud";
spinSpeed = 30.0;
spinRandomMin = -50.0;
spinRandomMax = 50.0;
useInvAlpha   = true;

colors[0]     = "1 0.745 0.50 1";
colors[1]     = "1.50 0.580 0.235 1";
colors[2]     = "0.50 0.250 0.00 1";
colors[3]     = "0.50 0.250 0.00 1";

sizes[0] = 0.0;
sizes[1] = 0.0;
sizes[2] = 0.5;
sizes[3] = 2.5;

times[0] = 0.0;
times[1] = 0.2;
times[2] = 0.8;
times[3] = 1.0;
};

datablock ParticleEmitterData(DirtEmitterC)
{
   ejectionPeriodMS = 1;
   periodVarianceMS = 0;
   ejectionVelocity = 25.0;
   velocityVariance = 0.0;
   ejectionOffset   = 0.0;
   thetaMin         = 0;
   thetaMax         = 5;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   orientOnVelocity = true;

   //lifetimeMS = 5000;
   particles = DirtParticleC;
};



datablock ExplosionData(DirtsprayExplosion)
{
   //explosionShape = "";
// soundProfile = 0;

   lifeTimeMS = 150;

   particleEmitter = PlayerFoamEmitter;
   particleDensity = 50;
   particleRadius = 0.2;

   faceViewer     = true;
   explosionScale = "1 1 1";

   shakeCamera = false;
   camShakeFreq = "10.0 11.0 10.0";
   camShakeAmp = "1.0 1.0 1.0";
   camShakeDuration = 0.5;
   camShakeRadius = 10.0;

   // Dynamic light
   lightStartRadius = 0;
   lightEndRadius = 2;
   lightStartColor = "0.6 0.6 0.9";
   lightEndColor = "0 0 0";
};


//projectile
datablock ProjectileData(DirtsprayProjectile)
{
   //projectileShapeName = "./shapes/arrow.dts";

   directDamage        = 0;
   directDamageType    = $DamageType::ArrowDirect;

   radiusDamage        = 0;
   damageRadius        = 0;
   radiusDamageType    = $DamageType::ArrowDirect;

   explosion           = DirtsprayExplosion;
//   particleEmitter     = DirtsprayTrailEmitter;

   muzzleVelocity      = 20;
   velInheritFactor    = 0;

   armingDelay         = 0;
   lifetime            = 500;
   fadeDelay           = 250;
   bounceElasticity    = 0;
   bounceFriction      = 0;
   isBallistic         = false;
   gravityMod = 0.0;

   hasLight    = false;
   lightRadius = 3.0;
   lightColor  = "0 0 0.5";
};


//////////
// item //
//////////
datablock ItemData(DirtsprayItem)
{
category = "Weapon";  // Mission editor category
className = "Weapon"; // For inventory system

// Basic Item Properties
shapeFile = "base/data/shapes/spraycan.dts";
rotate = false;
mass = 1;
density = 0.2;
elasticity = 0.2;
friction = 0.6;
emap = true;

//gui stuff
uiName = "Dirt Spray";
iconName = "Add-Ons/Tool_Fillcan/icon_fillcan";
doColorShift = true;
colorShiftColor = "0.50 0.250 0.00 1";

// Dynamic properties defined by the scripts
image = DirtsprayImage;
canDrop = true;
};

datablock ShapeBaseImageData(DirtsprayImage)
{
   // Basic Item properties
   shapeFile = "base/data/shapes/spraycan.dts";
   emap = true;

   // Specify mount point & offset for 3rd person, and eye offset
   // for first person rendering.
   mountPoint = 0;
   offset = "0 0 0";
   eyeOffset = 0; //"0.7 1.2 -0.5";
   rotation = eulerToMatrix( "0 0 0" );

   // When firing from a point offset from the eye, muzzle correction
   // will adjust the muzzle vector to point to the eye LOS point.
   // Since this weapon doesn't actually fire from the muzzle point,
   // we need to turn this off. 
   correctMuzzleVector = true;

   // Add the WeaponImage namespace as a parent, WeaponImage namespace
   // provides some hooks into the inventory system.
   className = "WeaponImage";

   // Projectile && Ammo.
   item = DirtsprayItem;
   ammo = " ";
   projectile = DirtsprayProjectile;
   projectileType = Projectile;

casing = "";
shellExitDir        = "1.0 -1.3 1.0";
shellExitOffset     = "0 0 0";
shellExitVariance   = 15.0;
shellVelocity       = 7.0;

   //melee particles shoot from eye node for consistancy
   melee = false;
   //raise your arm up or not
   armReady = true;

   doColorShift = true;
   colorShiftColor = DirtsprayItem.colorShiftColor;//"0.400 0.196 0 1.000";

stateName[0]                     = "Activate";
stateTimeoutValue[0]             = 0.15;
stateTransitionOnTimeout[0]       = "Ready";
stateSound[0] = weaponSwitchSound;

stateName[1]                     = "Ready";
stateTransitionOnTriggerDown[1]  = "Fire";
stateAllowImageChange[1]         = true;
stateSequence[1] = "Ready";

stateName[2]                    = "Fire";
stateTransitionOnTimeout[2]     = "Fire";
stateTransitionOnTriggerUp[2]    = "Reload";
stateTimeoutValue[2]            = 0.05;
stateFire[2]                    = true;
stateAllowImageChange[2]        = false;
stateSequence[2]                = "Fire";
stateScript[2]                  = "onFire";
stateWaitForTimeout[2] = true;
stateEmitter[2] = DirtEmitterC;
stateEmitterTime[2] = 0.05;
stateEmitterNode[2] = "muzzleNode";
stateSound[2] = sprayFireSound;
stateEjectShell[2]       = true;


stateName[3] = "Reload";
stateSequence[3]                = "Reload";
stateTransitionOnTriggerUp[3]     = "Ready";
stateTransitionOnTriggerDown[3]  = "Fire";
stateSequence[3] = "Ready";
};

function DirtsprayProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
if(%col.getDatablock().brickSizeX == 4 && %col.getDatablock().brickSizeY == 4)
{
%pos = getWords(%col.getTransform(),0,2);
%obj.client.dig_dirt--;
switch$(%normal)
{
case "0 0 1":
%pos = vectorAdd(%pos,"0 0 2");
case "0 0 -1":
%pos = vectorAdd(%pos,"0 0 -2");
case "0 1 0":
%pos = vectorAdd(%pos,"0 2 0");
case "0 -1 0":
%pos = vectorAdd(%pos,"0 -2 0");
case "1 0 0":
%pos = vectorAdd(%pos,"2 0 0");
case "-1 0 0":
%pos = vectorAdd(%pos,"-2 0 0");
}
%brick = new fxDTSBrick()
    {
client = %obj.client;
datablock = "brick4xCubeData";
position = %pos;
colorID = 8;
colorfxID = 0;
shapefxID = 0;
isPlanted = 1;
stackBL_ID = %obj.client.bl_id;
type = "dirt"; //dunno what this is for
isMineable = 1;
health = 10;
};
if(isObject(%brick))
{
%obj.client.brickgroup.add(%brick);
$Dig_placedDirt[%pos] = 1;
$server::BrickCount++;
//also negate dirt here I guess?
}
}
}
« Last Edit: March 11, 2010, 07:11:33 AM by Jaydee »


Okay I traced the values

Code: [Select]
Normal: 1.000000 0.000000 0.000000
Pos: -10.000000 0.591709 3.179381
Pos2: -11 1 4
Normal: 1.000000 0.000000 0.000000
Pos: -10.000000 0.591709 3.179381
Pos2: -11 1 4
Normal: 1.000000 0.000000 0.000000
Pos: -10.000000 0.968609 4.131611
Pos2: -11 1 4

vectorAdd doesn't seem to add to the original position.

The problem is within this:

Code: [Select]
%pos = getWords(%col.getTransform(),0,2);
switch$(%normal)
{
case "0 0 1":
%pos = vectorAdd(%pos,"0 0 2");
case "0 0 -1":
%pos = vectorAdd(%pos,"0 0 -2");
case "0 1 0":
%pos = vectorAdd(%pos,"0 2 0");
case "0 -1 0":
%pos = vectorAdd(%pos,"0 -2 0");
case "1 0 0":
%pos = vectorAdd(%pos,"2 0 0");
case "-1 0 0":
%pos = vectorAdd(%pos,"-2 0 0");
}


Code: [Select]
%pos = getWords(%col.getTransform(),0,2);
switch$(%normal)
{
case "0 0 1":
%pos = getWord(%pos,0) SPC getWord(%pos,1) SPC (getWord(%pos,2) + 2);
case "0 0 -1":
%pos = getWord(%pos,0) SPC getWord(%pos,1) SPC (getWord(%pos,2) - 2);
case "0 1 0":
%pos = getWord(%pos,0) SPC (getWord(%pos,1) + 2) SPC getWord(%pos,2);
case "0 -1 0":
%pos = getWord(%pos,0) SPC (getWord(%pos,1) - 2) SPC getWord(%pos,2);
case "1 0 0":
%pos = (getWord(%pos,0) + 2) SPC getWord(%pos,1) SPC getWord(%pos,2);
case "-1 0 0":
%pos = (getWord(%pos,0) - 2) SPC getWord(%pos,1) SPC getWord(%pos,2);
}

Okay it now works:

Code: [Select]
function DirtsprayProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
echo("Normal: " @ %normal);
echo("Pos: " @ %pos);
%pos = %col.getPosition();

%x = getWord(%pos, 0);
%y = getWord(%pos, 1);
%z = getWord(%pos, 2);
switch(%normal)
{
case "0 0 1":
%pos2 = %x SPC %y SPC %z+2;
case "0 0 -1":
%pos2 = %x SPC %y SPC %z-2;
case "0 1 0":
%pos2 = %x SPC %y+2 SPC %z;
case "0 -1 0":
%pos2 = %x SPC %y-2 SPC %z;
case "1 0 0":
%pos2 = %x+2 SPC %y SPC %z;
case "-1 0 0":
%pos2 = %x-2 SPC %y SPC %z;
default:
echo("** Normals Error");
}

echo("Pos2: " @ %pos2);

%x2 = getWord(%pos2, 0);
%y2 = getWord(%pos2, 1);
%z2 = getWord(%pos2, 2);

if(%col.getDatablock().brickSizeX == 4 && %col.getDatablock().brickSizeY == 4 && %obj.client.dig_dirt >= 1 ) //&& !$Dig_hasDirt[%pos2])
{
%obj.client.dig_dirt--;
Dig_PlaceDirt(%pos2,%obj.client);
$Dig_placedDirt[%pos2] = 1;
$Dig_hasDirt[%pos2] = 1;
}
else if(%pos2 != %col.getPosition())
echo("*** The pos2 is the same as the col pos thing errored");
else if($Dig_hasDirt[%pos2] != 0)
echo("*** Has dirt on pos thing errored");
else if($Dig_placedDirt[%pos2])
echo("*** Placed dirt thing errored");
else if(mAbs(%x2) <= 11 && mAbs(%y2) <= 11 && %z2 <= 10 && %z2 >= 0)
echo("*** mAbs thing errored");
}

The problem now is, whenever the normals are "0 -1 0", "0 1 0", "0 0 1", and "0 0 -1", the block always plants on top of the block. The x axis is fine, but the two other axes always add vectors to the top.
« Last Edit: March 13, 2010, 05:26:41 AM by Jaydee »

I want to implement dirt/cement planting, but I want it like how Destiny does it in Blockcraft, it stays on the 4x4 grid. I want to do this using an item/tool, which when it fires, it places a dirt or cement or any 4x4 brick.

:|

Also,

Code: [Select]
%x = getWord(%pos, 0);
%y = getWord(%pos, 1);
%z = getWord(%pos, 2);
switch(%normal)
{
case "0 0 1":
%pos2 = %x SPC %y SPC %z+2;
case "0 0 -1":
%pos2 = %x SPC %y SPC %z-2;
case "0 1 0":
%pos2 = %x SPC %y+2 SPC %z;
case "0 -1 0":
%pos2 = %x SPC %y-2 SPC %z;
case "1 0 0":
%pos2 = %x+2 SPC %y SPC %z;
case "-1 0 0":
%pos2 = %x-2 SPC %y SPC %z;
default:
echo("** Normals Error");
}

Replace all that crap with this:

Code: [Select]
%pos2 = vectorAdd(%pos,vectorScale(%normal,2));