Author Topic: Can someone check to see if my code is correct? (Actually added code)  (Read 830 times)

The code is loving huge so I'm going to PM it to whoever wants to proofread it.  What it is is an edited version of the deflector. I want to make sure that it's all correct before I put it in an add on folder.  

//Mega Hand X Grade 1
//Reskin of deflector, somewhat stronger

//Deflector
//Do away with projectiles, maybe even send them right back.

datablock AudioProfile(MegaHand1XSound)
{
   filename    = "./Deflect.wav";
   description = AudioDefault3d;
   preload = true;
};
datablock AudioProfile(RedirectSound)
{
   filename    = "./Redirected.wav";
   description = AudioDefault3d;
   preload = true;
};

datablock ParticleData(MegaHand1XParticle)
{
   dragCoefficient      = 0.1;
   gravityCoefficient   = 0;
   inheritedVelFactor   = 0;
   constantAcceleration = 0.0;
   lifetimeMS           = 400;
   lifetimeVarianceMS   = 0;
   textureName          = "base/data/particles/thinring";
   colors[0]     = "0.2 0.9 0 0.6";
   colors[1]     = "0.4 0.9 0 0.5";
   sizes[0]      = 0.2;
   sizes[1]      = 18;
   times[0]     = 0;
   times[1]     = 1;

   useInvAlpha = true;
};
datablock ParticleEmitterData(MegaHand1XEmitter)
{
   ejectionPeriodMS = 6;
   periodVarianceMS = 0;
   ejectionVelocity = 44;
   velocityVariance = 0;
   ejectionOffset   = 0;
   thetaMin         = 0;
   thetaMax         = 0;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "MegaHand1XParticle";
   UIName = "Mega Hand X Grade 1";
};
datablock ItemData(MegaHand1Item)
{
   category = "Weapon";  // Mission editor category
   className = "Weapon"; // For inventory system

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

   //gui stuff
   uiName = "Mega Hand Grade 1 X";
   iconName = "./Icon_mghand1 X";
   doColorShift = true;
   colorShiftColor = "0.50 1 0.1 1.000";

    // Dynamic properties defined by the scripts
   image = MegaHand1XImage;
   canDrop = false;
};

datablock ShapeBaseImageData(MegaHandImage)
{
   shapeFile = "./MegaHand1X.dts";
   emap = true;

   mountPoint = 0;
   offset = "0 0 0";
   eyeOffset = 0; //"0.7 1.2 -0.5";
   rotation = eulerToMatrix( "0 0 0" );

   correctMuzzleVector = true;

   className = "WeaponImage";

   // Projectile && Ammo.
   item = MegaHand1XItem;
   ammo = " ";
   projectileType = ""; //We use a connical search rather than a projectile.

   melee = false;
   armReady = true;

   doColorShift = true;
   colorShiftColor = MegaHand1XItem.colorShiftColo r;//"0.0 0.0 0.75 0.85";

   // Initial start up state
   stateName[0]                       = "Activate";
   stateTimeoutValue[0]            = 1;
   stateTransitionOnTimeout[0]        = "Ready";
   stateSound[0]                  = weaponSwitchSound;

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

   stateName[2]                  = "Fire";
   stateEmitter[2]                  = DeflectorEmitter;
   stateScript[2]                  = "onFire";
   stateEmitterTime[2]               = 0.05;
   stateEmitterNode[2]               = "muzzleNode";
   stateTransitionOnTriggerUp[2]      = "AmmoCheck";
   stateAllowImageChange[2]         = false;
   StateSound[2]                  = DeflectorSound;

   stateName[3]                  = "AmmoCheck"; //An ammo system is the only way I know to alter the state of a mounted image through script.
   stateTransitionOnNoAmmo[3]         = "Reload";
   StateTransitionOnAmmo[3]         = "Ready";

   stateName[4]                  = "Reload";
   stateTransitionOnTimeout[4]         = "Ready";
   stateTimeoutValue[4]            = 1;
};

function MegaHand1XImage::onFire(%this, %obj, %slot)
{
   %obj.setImageAmmo(0, 0); //Disable the gun.
   %client = %obj.client;
   %eye = %client.player.getEyeTransform(); //Because I hate typing it out over and over again.
   %mask = $TypeMasks::ProjectileObjectType; //I was originally planning to make it shove players around, but I decided this should be better for medium-long range encounters.
   InitContainerRadiusSearch(%eye, 12, %mask);
   while(isObject(%Proj = containerSearchNext()))
   {
      if(!miniGameCanDamage(%Proj, %obj) && (isObject(%proj.client.minigame) || isObject(%client.minigame))) //Don't touch it if it's involved in a different minigame
            continue;
      %velAvg = (mAbs(getWord(%proj.getVelocity(), 0)) + mAbs(getWord(%proj.getVelocity(), 1)) + mAbs(getWord(%proj.getVelocity(), 2))) / 3;
      if(!%proj.origVelocity || %proj.origVelocity < %proj.getDatablock().muzzleVelocity / 2) //We don't want too small of an original velocity to base our reflections on, otherwise we couldn't get it above half normal speed.
         %proj.origVelocity = %velAvg; //Speed cap is based on how fast the projectile was at first deflection.
      %repelForce = ((20 - vectorDist(%eye, %proj.getTransform())) / 6) * %velAvg; //Allow us to boost the speed based on what it already is, instead of the default speed.
      if(%repelForce > %proj.origVelocity * 2.25)
         %repelForce = (2.25 * %proj.origVelocity); //We have to cap it at some point.
      if(%repelForce <= %proj.getDatablock().muzzleVelocity / 2)
         %repelForce = (%proj.getDatablock().muzzleVelocity / 2); //Also imposing a minimum.
      %repelDir = vectorNormalize(vectorSub(%proj.getTransform(), %eye));

         %anglediff = vectorSub(%repelDir,vectorNormalize(%client.player.getEyeVector()));
      %anglediffavg = (mAbs(getWord(%angleDiff, 0)) + mAbs(getWord(%angleDiff, 1)) + mAbs(getWord(%angleDiff, 2))) / 3;
      if(%anglediffavg > 0.3) //Makeshift vector angle comparison. It doesn't work as accurately as I wish it did, but I'm not all that good with vectors.
            continue;

      if(vectorDist(%eye, %proj.getTransform()) <= 6 && isObject(%proj.client.player) && %client != %proj.client)
      {
         %ownerDir = vectorNormalize(vectorSub(%proj.client.player.getEyeTransform(), %eye));
         %ownerAngleDiff = vectorSub(%ownerDir, vectorNormalize(%client.player.getEyeVector()));
         %ownerAngleDiffAvg = (mAbs(getWord(%ownerAngleDiff, 0)) + mAbs(getWord(%ownerAngleDiff, 1)) + mAbs(getWord(%ownerAngleDiff, 2))) / 3; //I thought I've seen a cone-search function somewhere before...
         if(%anglediffavg <= 0.5) //If they're out of our sight, we don't send it at them.
            %repelDir = vectorNormalize(vectorSub(%proj.client.player.getEyeTransform(), %proj.getTransform())); //Step in and tell us where it should go.
      }
      
      %newVelocity = vectorScale(%repelDir, %repelForce); //Get our final calculations as to where we should shoot this thing.
      
      serverPlay3d(RedirectSound, %proj.getPosition());
      %obj.setImageAmmo(0, 1); //Reenable the gun if we actually used it on something
      
      %p = new Projectile() //Because Projectile::Redirect didn't work, and Projectile::SetVelocity doesn't exist for some reason.
      {
         initialVelocity      = %newVelocity;
         origVelocity      = %proj.origVelocity;
         initialPosition      = %proj.getPosition();
         datablock         = %proj.getDatablock();
         sourceObject      = %proj.client.player;
         sourceSlot         = %proj.sourceSlot;
         client            = %client; //Change the owner to us so we can damage the original attacker.
         scale            = %proj.getScale();
      };
      missionCleanup.add(%p);
      %proj.delete(); //Do away with the old one so we don't get facerocketed.
   }
}
« Last Edit: October 07, 2015, 12:11:16 PM by Space1255 »

Why not test it first to see if it works?

Why not test it first to see if it works?
Because I'm in school right now and I have a lot of stuff to do tonight, leaving me with little time to test it myself.

Upload it here as a .cs, you'll get more help

-nvm this post, it was dumb-

I'll probably just make it raw text and have the text be small.
Done
« Last Edit: October 07, 2015, 12:10:59 PM by Space1255 »

Datablock = %proj.getDatablock();
Pretty sure this needs to be .getDatablock().getName(); should it not? On second thought, both are probably correct.

I just used whatever was in the original deflector code, so I assume that was correct. I'm not doubting that yours is also correct.

Datablock = %proj.getDatablock();
Pretty sure this needs to be .getDatablock().getName(); should it not? On second thought, both are probably correct.
Both should work either way, the name will refer back to the ID anyways.

The only thing I'm going to say is that an add-on of sorts may be adding additional variables to the projectile that you're not accounting for. I'm not sure if this is ever a case but it the possibility is there.

You should clone the projectile with a new initialvelocity and initialposition.
Code: [Select]
      %p = new Projectile() //Because Projectile::Redirect didn't work, and Projectile::SetVelocity doesn't exist for some reason.
      {
         initialVelocity      = %newVelocity;
         origVelocity      = %proj.origVelocity;
         initialPosition      = %proj.getPosition();
         datablock         = %proj.getDatablock();
         sourceObject      = %proj.client.player;
         sourceSlot         = %proj.sourceSlot;
         client            = %client; //Change the owner to us so we can damage the original attacker.
         scale            = %proj.getScale();
      };
      missionCleanup.add(%p);
      %proj.delete();
To
Code: [Select]
      %proj.oldname = %proj.getName();
      %proj.setName("tempproj");
      %p = new Projectile(newproj : tempproj) //Because Projectile::Redirect didn't work, and Projectile::SetVelocity doesn't exist for some reason.
      {
         initialVelocity      = %newVelocity;
         initialPosition      = %proj.getPosition();
         client            = %client; //Change the owner to us so we can damage the original attacker.
      };
      missionCleanup.add(%p);
      %p.setname(%proj.oldname);
      %proj.delete();

To
Code: [Select]
     %proj.oldname = %proj.getName();
      %proj.setName("tempproj");
      %p = new Projectile(newproj : tempproj) //Because Projectile::Redirect didn't work, and Projectile::SetVelocity doesn't exist for some reason.
      {
         initialVelocity      = %newVelocity;
         initialPosition      = %proj.getPosition();
         client            = %client; //Change the owner to us so we can damage the original attacker.
      };
      missionCleanup.add(%p);
      %p.setname(%proj.oldname);
      %proj.delete();
Pro tip: You don't need to name the new object for it to inherit from an object. You can just do:
Code: [Select]
//Stuff here.

%p = new projectile(: tempProj)
{
         //Stuff here.
};

//Other stuff here.

I think(not 100% sure) that you could even do: Nope. That wasn't it, but I remember seeing something similar that worked.
Code: [Select]
%p = new projectile(: (%proj))
« Last Edit: October 08, 2015, 07:47:35 AM by jes00 »

It's because of the way Blockland handles various parameters. I would venture a guess putting it in middle of brackets makes it return a value so it is handled (:objectID) instead of getting routed to some C++ mechanism for division.

Pro tip: You don't need to name the new object for it to inherit from an object. You can just do:
Oh okay, that's handy.