Author Topic: Using schedules to call functions + more problems (NEW)  (Read 1404 times)

This is really pissing me off. I'm trying to call another function twice within a function, with the second having the schedule so that it's spaced out. The purpose is that it's an easy way to make burst fire without cluttering sequences. However, the second function is called immediately - there is no delay.


function j_CarbineAImage::onBurstFire(%this,%obj,%slot)
{
   j_CarbineAImage::onFire(%this,%obj,%slot,0.0002);
   %obj.schedule(133,j_CarbineAImage::onFire(%this,%obj,%slot,0.0002));
   %obj.playThread(0, shiftLeft);
   %obj.playThread(2, shiftRight);
}

function j_CarbineAImage::onFire(%this,%obj,%slot,%spread)
{
   %projectile = %this.Projectile;
   %spread = 0.00032;
   %shellcount = 1;

   %obj.schedule(100, playthread, 0, plant);

   serverPlay3D(j_ARShot1Sound, %obj.getPosition());
   
   for(%shell=0; %shell<%shellcount; %shell++)
   {
      %vector = %obj.getMuzzleVector(%slot);
      %objectVelocity = %obj.getVelocity();
      %vector1 = VectorScale(%vector, %projectile.muzzleVelocity);
      %vector2 = VectorScale(%objectVelocity, %projectile.velInheritFactor);
      %velocity = VectorAdd(%vector1,%vector2);
      %x = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %y = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %z = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z);
      %velocity = MatrixMulVector(%mat, %velocity);

      %p = new (%this.projectileType)()
      {
         dataBlock = %projectile;
         initialVelocity = %velocity;
         initialPosition = %obj.getMuzzlePoint(%slot);
         sourceObject = %obj;
         sourceSlot = %slot;
         client = %obj.client;
      };
      MissionCleanup.add(%p);
   }
}


Help please!
« Last Edit: December 27, 2015, 01:08:53 AM by Gumba Jonny »

It should be %this.schedule(133, onFire, %obj, %slot, 0.0002);

That worked perfectly, thanks!

Well I figure I'd might as well use this thread to discuss and solve other problems.
You could see that although calling the script twice effectively works for firing bullets, you're missing out on calling the emitter twice and ejecting two shells. Those are handled by sequences.
Now, my current dilemma is trying to create an emitter through the function in the same way you'd create a projectile. The console error I get for the following code is this - and I'm sure there would be a lot more underlying problems as well (lifetime of emitter, etc.):

The code:

function j_CarbineAImage::onFire(%this,%obj,%slot,%spread)
{
...
   //emitter by code
   %vector = %obj.getMuzzleVector(%slot);
   %objectVelocity = %obj.getVelocity();
   %velocity = VectorAdd(%vector,%objectVelocity);
   %e = new ParticleEmitter()
   {
      dataBlock = gunFlashEmitter;
      initialVelocity = %velocity;
      initialPosition = %obj.getMuzzlePoint(%slot);
      sourceObject = %obj;
      sourceSlot = %slot;
      client = %obj.client;
   };
}


The error:
Add-Ons/Weapon_TheGunsPack/Weapon_CarbineA.cs (0): Unable to instantiate non-conobject class particleEmitter.

Apparently particle emitters aren't conobjects, yet projectiles are? Should I use something else? Or do I have to use the old stuffty workaround of making a projectile that uses the emitter I want in some way?

I got the name ParticleEmitter from that old Torque pdf Appendix A, by the way.
« Last Edit: December 23, 2015, 10:56:39 PM by Gumba Jonny »

you can't create emitters on their own those are created on the client side, you can create emitter nodes but it is not recommended for weapons, you should use the weapon state emitter

for something like a muzzle flash you can create a projectile that has an explosion that looks like a muzzle flash and all you would do is create the projectile and then instantly explode it
thing is i think you cant really do the muzzle flash's direction but i don't know for sure

thing is i think you cant really do the muzzle flash's direction but i don't know for sure
Set initialVelocity on the projectile to the direction you want the explosion emitter to face, then set lifetime to 0 so it'll explode instantly on it's own

However you shouldn't be doing this at all for a muzzle flash, better to use the state emitter system because it'll look right on the client side

Well the easiest solution was to just extend the time of the emitter on the sequence that fires the double shot, and truth be told it looks just fine so that problem's solved.
Now I have another - ejecting shells. Is there a function for ejecting shells? What else could I do? I'm trying to avoid using lots of sequences, so basically stateEject[] is my last resort.

Well the easiest solution was to just extend the time of the emitter on the sequence that fires the double shot, and truth be told it looks just fine so that problem's solved.
Now I have another - ejecting shells. Is there a function for ejecting shells? What else could I do? I'm trying to avoid using lots of sequences, so basically stateEject[] is my last resort.
this is your best resort, you can create an explosion that has debris but its a lot harder to control

I would recommend just making 2 fire sequences, it's not a big deal

Good news - I don't have any more problems related to this thread any more!
But I've got some other gun related problems:
The chargeup goes on, but it doesn't stop at 10. The fire sequences ("Fire" and "SFire") don't work at all either. I figure it's a simple problem, but I can't see it right now. Help!

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

   stateName[1]                     = "Ready";
   stateScript[1]               = "onReady";
   stateTransitionOnTriggerDown[1]  = "Choice";
   stateAllowImageChange[1]         = true;
   stateSequence[1]   = "Ready";

   stateName[2]               = "Choice";
   stateWaitForTimeout[2]         = false;
   stateTimeoutValue[2]         = 0.25;
   stateSound[2]               = SnowgunStartSound;
   stateTransitionOnTriggerUp[2]   = "SFire";
   stateTransitionOnTimeout[2]      = "Prime";
   
   stateName[3]               = "Prime";
   stateScript[3]               = "onPrime";
   stateWaitForTimeout[3]         = false;
   stateAllowImageChange[3]      = false;
   stateTimeoutValue[3]         = 0.25;
   stateSound[3]               = SnowgunLoopSound;
   stateSequence[3]            = "Cycle";
   stateTransitionOnTimeout[3]      = "PrimeCycle";
   stateTransitionOnTriggerUp[3]   = "Fire";
   
   stateName[4]               = "Fire";
   stateScript[4]               = "onFire";
   stateTimeoutValue[4]         = 0.08;
   stateAllowImageChange[4]      = false;
   stateWaitForTimeout[4]         = true;
   stateEmitter[4]               = SnowgunMuzzleEmitter;
   stateEmitterNode[4]            = "muzzleNode";
   stateEmitterTime[4]            = 0.1;
   stateTransitionOnTriggerUp[4]      = "Ready";
   stateTransitionOnTriggerDown[4]   = "Fire";
   
   stateName[5]               = "SFire";
   stateScript[5]               = "onSFire";
   stateAllowImageChange[5]      = true;
   stateTimeoutValue[5]         = 0.15;
   stateSequence[5]            = "Cycle";
   stateWaitForTimeout[5]         = true;
   stateEmitter[5]               = SnowgunMuzzleEmitter;
   stateEmitterNode[5]            = "muzzleNode";
   stateEmitterTime[5]            = 0.1;
   stateTransitionOnTriggerUp[5]      = "Ready";
   
   stateName[6]               = "PrimeCycle";
   stateSound[6]               = SnowgunLoopSound;
   stateTimeoutValue[6]         = 0.01;
   stateTransitionOnTimeout[6]      = "Prime";
};

function SnowgunImage::onReady(%this,%obj,%slot)
{
   %obj.snowballs[%obj.currTool] = 0;
}

function SnowgunImage::onPrime(%this,%obj,%slot)
{
   if(%obj.snowballs[%obj.currTool] >= 10)
   {
      %obj.snowballs[%obj.currTool] = 10;
      %obj.setImageTrigger(0,0);
   }
   else
   {
      %obj.snowballs[%obj.currTool]++;
      serverPlay3D(SnowgunChargeSound, %obj.getPosition());
      %obj.playThread(0, rotcw);
      %obj.playThread(2, rotccw);
   }
}

function SnowgunImage::onFire(%this,%obj,%slot)
{   
   %obj.playThread(0, shiftRight);
   %obj.playThread(2, shiftLeft);
   serverPlay3D(SnowgunFireSound, %obj.getPosition());
   %projectile = %this.Projectile;
   %spread = 0.003;
   %shellcount = 1;
   
   for(%shell=0; %shell<%shellcount; %shell++)
   {
      %vector = %obj.getMuzzleVector(%slot);
      %objectVelocity = %obj.getVelocity();
      %vector1 = VectorScale(%vector, %projectile.muzzleVelocity);
      %vector2 = VectorScale(%objectVelocity, %projectile.velInheritFactor);
      %velocity = VectorAdd(%vector1,%vector2);
      %x = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %y = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %z = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z);
      %velocity = MatrixMulVector(%mat, %velocity);

      %p = new (%this.projectileType)()
      {
         dataBlock = %projectile;
         initialVelocity = %velocity;
         initialPosition = %obj.getMuzzlePoint(%slot);
         sourceObject = %obj;
         sourceSlot = %slot;
         client = %obj.client;
      };
      MissionCleanup.add(%p);
   }
   
   if(%obj.snowballs[%obj.currTool] > 0)
   {
      %obj.schedule(80, setImageTrigger, 0, 1);
      %obj.snowballs[%obj.currTool]--;
   }
   else
   {
      %obj.schedule(80, setImageTrigger, 0, 0);
   }
}

function SnowgunImage::onSFire(%this,%obj,%slot)
{   
   %obj.playThread(0, shiftRight);
   %obj.playThread(2, shiftLeft);
   serverPlay3D(SnowgunFireSound, %obj.getPosition());
   %projectile = %this.Projectile;
   %spread = 0.0006;
   %shellcount = 1;
   
   for(%shell=0; %shell<%shellcount; %shell++)
   {
      %vector = %obj.getMuzzleVector(%slot);
      %objectVelocity = %obj.getVelocity();
      %vector1 = VectorScale(%vector, (%projectile.muzzleVelocity*1.3));
      %vector2 = VectorScale(%objectVelocity, %projectile.velInheritFactor);
      %velocity = VectorAdd(%vector1,%vector2);
      %x = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %y = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %z = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z);
      %velocity = MatrixMulVector(%mat, %velocity);

      %p = new (%this.projectileType)()
      {
         dataBlock = %projectile;
         initialVelocity = %velocity;
         initialPosition = %obj.getMuzzlePoint(%slot);
         sourceObject = %obj;
         sourceSlot = %slot;
         client = %obj.client;
      };
      MissionCleanup.add(%p);
   }
}
« Last Edit: December 25, 2015, 05:30:14 PM by Gumba Jonny »

Okay, so rather than doing that schedule stuff with setImageTrigger, I've attempted to use setImageLoaded instead. Here's the setup. I'm in the middle of changing it, but as it stands, this crashes the game.
 "SFire" doesn't work still, but the game crashes as soon as the loaded amount of snowballs hits 10, so the game basically crashes when going through "FireCheck" or another sequence, as far as I know.

   stateName[0]                     = "Activate";
   stateWaitForTimeout[0]         = true;
   stateTimeoutValue[0]             = 0.25;
   stateTransitionOnTimeout[0]       = "Ready";
   stateSound[0]               = weaponSwitchSound;

   stateName[1]                     = "Ready";
   stateScript[1]               = "onReady";
   stateTransitionOnTriggerDown[1]  = "Choice";
   stateAllowImageChange[1]         = true;
   stateSequence[1]   = "Ready";

   stateName[2]               = "Choice";
   stateWaitForTimeout[2]         = false;
   stateTimeoutValue[2]         = 0.25;
   stateSound[2]               = SnowgunStartSound;
   stateTransitionOnTriggerUp[2]  = "SFire";
   stateTransitionOnTimeout[2]      = "Prime";
   
   stateName[3]               = "Prime";
   stateScript[3]               = "onPrime";
   stateWaitForTimeout[3]         = true;
   stateAllowImageChange[3]      = false;
   stateTimeoutValue[3]               = 0.06;
   stateSound[3]               = SnowgunLoopSound;
    stateSequence[3]            = "Close";
   stateTransitionOnTimeout[3]      = "Check";
   stateTransitionOnTriggerUp[3]      = "Initiate";
   
   stateName[4]               = "Fire";
   stateScript[4]               = "onFire";
   stateTimeoutValue[4]         = 0.08;
   stateAllowImageChange[4]      = false;
   stateWaitForTimeout[4]         = true;
   stateEmitter[4]               = SnowgunMuzzleEmitter;
   stateEmitterNode[4]            = "muzzleNode";
   stateEmitterTime[4]            = 0.05;
   stateTransitionOnNotLoaded[4]      = "Ready";
   stateTransitionOnLoaded[4]   = "Check";
   
   stateName[5]               = "SFire";
   stateScript[5]               = "onSFire";
   stateAllowImageChange[5]      = true;
   stateTimeoutValue[5]         = 0.10;
    stateSequence[5]            = "PullOpen";
   stateWaitForTimeout[5]         = true;
   stateEmitter[5]               = SnowgunMuzzleEmitter;
   stateEmitterNode[5]            = "muzzleNode";
   stateEmitterTime[5]            = 0.1;
   stateTransitionOnTriggerUp[5]      = "Ready";
   
   stateName[6]               = "Check";
   stateWaitForTimeout[6]         = false;
   stateSound[6]               = SnowgunLoopSound;
   stateTimeoutValue[6]         = 0.01;
   stateTransitionOnLoaded[6]      = "FireCheck";
   stateTransitionOnTimeout[6]      = "Prime";
   
   stateName[7]               = "Initiate";
   stateScript[7]               = "onInitiate";
   stateWaitForTimeout[7]         = true;
   stateSound[7]               = SnowgunLoopSound;
   stateTimeoutValue[7]         = 0.01;
   stateTransitionOnLoaded[7]      = "FireCheck";
   stateTransitionOnNotLoaded[7]      = "Prime";
   
   stateName[8]               = "FireCheck";
   stateScript[8]               = "onFireCheck";
   stateWaitForTimeout[8]         = true;
   stateSound[8]               = SnowgunLoopSound;
   stateTimeoutValue[8]         = 0.01;
   stateTransitionOnLoaded[8]      = "Fire";
   stateTransitionOnNotLoaded[8]      = "Ready";
};

function SnowgunImage::onReady(%this,%obj,%slot)
{
   %obj.snowballs[%obj.currTool] = 0;
   %obj.setImageLoaded(0,0);
}

function SnowgunImage::onPrime(%this,%obj,%slot)
{
   if(%obj.snowballs[%obj.currTool] >= 10)
   {
      %obj.snowballs[%obj.currTool] = 10;
      %obj.setImageLoaded(0,1);
   }
   else
   {
      %obj.snowballs[%obj.currTool]++;
      serverPlay3D(SnowgunChargeSound, %obj.getPosition());
      %obj.playThread(0, rotcw);
      %obj.playThread(2, rotccw);
   }
}

function SnowgunImage::onInitiate(%this,%obj,%slot)
{
   if(%obj.snowballs[%obj.currTool] > 0)
   {
      %obj.setImageLoaded(0,1);
   }
   else
   {
      %obj.setImageLoaded(0,0);
   }
}

function SnowgunImage::onFireCheck(%this,%obj,%slot)
{
   if(%obj.snowballs[%obj.currTool] > 0)
   {
      %obj.setImageLoaded(0,1);
   }
   else
   {
      %obj.setImageLoaded(0,0);
   }
}

function SnowgunImage::onFire(%this,%obj,%slot)
{   
   %obj.playThread(0, shiftRight);
   %obj.playThread(2, shiftLeft);
   serverPlay3D(SnowgunFireSound, %obj.getPosition());
   %projectile = %this.Projectile;
   %spread = 0.003;
   %shellcount = 1;
   
   for(%shell=0; %shell<%shellcount; %shell++)
   {
      %vector = %obj.getMuzzleVector(%slot);
      %objectVelocity = %obj.getVelocity();
      %vector1 = VectorScale(%vector, %projectile.muzzleVelocity);
      %vector2 = VectorScale(%objectVelocity, %projectile.velInheritFactor);
      %velocity = VectorAdd(%vector1,%vector2);
      %x = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %y = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %z = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z);
      %velocity = MatrixMulVector(%mat, %velocity);

      %p = new (%this.projectileType)()
      {
         dataBlock = %projectile;
         initialVelocity = %velocity;
         initialPosition = %obj.getMuzzlePoint(%slot);
         sourceObject = %obj;
         sourceSlot = %slot;
         client = %obj.client;
      };
      MissionCleanup.add(%p);
   }
   
   if(%obj.snowballs[%obj.currTool] > 0)
   {
      %obj.setImageLoaded(0,1);
      %obj.snowballs[%obj.currTool]--;
   }
   else
   {
      %obj.setImageLoaded(0,0);
   }
}

function SnowgunImage::onSFire(%this,%obj,%slot)
{   
   %obj.playThread(0, shiftRight);
   %obj.playThread(2, shiftLeft);
   serverPlay3D(SnowgunFireSound, %obj.getPosition());
   %projectile = %this.Projectile;
   %spread = 0.0006;
   %shellcount = 1;
   
   for(%shell=0; %shell<%shellcount; %shell++)
   {
      %vector = %obj.getMuzzleVector(%slot);
      %objectVelocity = %obj.getVelocity();
      %vector1 = VectorScale(%vector, (%projectile.muzzleVelocity*1.3));
      %vector2 = VectorScale(%objectVelocity, %projectile.velInheritFactor);
      %velocity = VectorAdd(%vector1,%vector2);
      %x = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %y = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %z = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
      %mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z);
      %velocity = MatrixMulVector(%mat, %velocity);

      %p = new (%this.projectileType)()
      {
         dataBlock = %projectile;
         initialVelocity = %velocity;
         initialPosition = %obj.getMuzzlePoint(%slot);
         sourceObject = %obj;
         sourceSlot = %slot;
         client = %obj.client;
      };
      MissionCleanup.add(%p);
   }
}


« Last Edit: December 25, 2015, 07:05:55 PM by Gumba Jonny »

So to fix the last two problems I just changed around the sequences and used a mix my last two setups that I posted (using setImageTrigger and setImageAmmo). The weapon works perfectly. Vague I know, and I would attach the code now, but I want to release the weapon in a few days so I kind of don't want to give the whole thing away right now. Sorry :(

Anyway, I have another issue: using armor::onTrigger to use setImageTrigger (firing with a right click basically).
The code:
package DualGunFire
{
   function Armor::onTrigger(%this, %obj, %player, %slot, %val)
   {
      if(%player.getMountedImage(0) $= DualGunImage.getID() && %slot $= 4 && %val)
    {
      %a = player.getMountedObject(0);
      %a.setImageTrigger(1,1);
   }
   return Parent::onTrigger(%this, %player, %slot, %val);
   }
};   
ActivatePackage(DualGunFire);


The console error:

Add-Ons/Weapon_Guns_Dual/Weapon_DualGun.cs (291): Unable to find object: '0' attempting to call function 'getMountedImage'
BackTrace: ->[sportBallsPackage]Armor::onTrigger->[PirateCannonPackage]Armor::onTrigger->[TankPackage]Armor::onTrigger->[DualGunFire]Armor::onTrigger



%a = player.getMountedObject(0);

 whats wrong with that statement?



function Armor::onTrigger(%this, %obj, %player, %slot, %val)

return Parent::onTrigger(%this, %player, %slot, %val);


Look at the arguments, they should be the same.



You should also check if the player is an object just before that if statement.


Well here's what I came up with, and it works!

package DualGunFire
{
   function Armor::onTrigger(%this, %player, %slot, %val)
   {
      if(%player.getMountedImage(0) $= DualGunImage.getID() && %slot $= 4 && %val)
    {
      %player.setImageTrigger(1,1);
   }
   return Parent::onTrigger(%this, %player, %slot, %val);
   }
};   
ActivatePackage(DualGunFire);

Thanks for the help.