Author Topic: is there a way to interrupt an emitter on an image  (Read 1571 times)

i have a wepon that charges up and it does an emitter while its charging and i want to turn off that emitter when the charge is released early. right now it continues to play the emitter for the full defined duration even after switching states

If you define a different datablock for the state emitter in the proceeding state(s), it should overwrite the previous one

For example:
Code: [Select]
stateEmitter[0] = "YourInitialParticleEmitter";
stateEmitterTime[0] = 1;
stateEmitterNode[0] = "muzzleNode";

stateEmitter[1] = "YourSecondParticleEmitter";
stateEmitterTime[1] = 1;
stateEmitterNode[1] = "muzzleNode";

stateEmitter[2] = "YourThirdParticleEmitter";
stateEmitterTime[2] = 1;
stateEmitterNode[2] = "muzzleNode";

that does not seem to be the case unless im missing something obvious

Code: [Select]
stateName[3] = "Smoke";
stateTimeoutValue[3] = 0.4;
stateScript[3] = "onMisfire";
stateTransitionOnTimeout[3] = "Reload";
stateEmitter[3] = rocketLauncherSmokeEmitter;
stateEmitterTime[3] = 0.3;
stateEmitterNode[3] = "muzzleNode";
stateSound[3] = rocketFireSound;
stateWaitForTimeout[3] = true;

...

stateName[5] = "Charge";
stateTimeoutValue[5] = 1.5;
stateScript[5] = "onBoltback";
stateTransitionOnTimeout[5] = "Fire";
stateTransitionOnTriggerUp[5] = "Smoke";
stateEmitter[5] = bigBangChargeEmitter;
stateEmitterTime[5] = 1.35;
stateEmitterNode[5] = "muzzleNode";
stateSound[5] = bigBangChargeSound;
stateWaitForTimeout[5] = false;

both emitters will play at the same time on the same node

in your example what is happening is that you are going from the charging state while holding click, then when you release click early it goes straight to the abort (smoke) state which is also creating an emitter. this would cause the appearance of both emitters happening in succession so quickly they may seem to overlap. you need to create a state in-between with no emitter that will be a delay before you swap to the image state with the next emitter.

Code: [Select]
stateName[3] = "Smoke";
stateTimeoutValue[3] = 0.4;
stateScript[3] = "onMisfire";
stateTransitionOnTimeout[3] = "Reload";
stateEmitter[3] = rocketLauncherSmokeEmitter;
stateEmitterTime[3] = 0.3;
stateEmitterNode[3] = "muzzleNode";
stateSound[3] = rocketFireSound;
stateWaitForTimeout[3] = true;

stateName[4] = "Delay";
stateTimeoutValue[4] = 0.4;
stateScript[4] = "onDelay";
stateTransitionOnTimeout[4] = "Smoke";
stateWaitForTimeout[4] = true;

stateName[5] = "Charge";
stateTimeoutValue[5] = 1.5;
stateScript[5] = "onBoltback";
stateTransitionOnTimeout[5] = "Fire";
stateTransitionOnTriggerUp[5] = "Delay";
stateEmitter[5] = bigBangChargeEmitter;
stateEmitterTime[5] = 1.35;
stateEmitterNode[5] = "muzzleNode";
stateSound[5] = bigBangChargeSound;
stateWaitForTimeout[5] = false;

in this example, onTriggerUp in the "Charge" image state will carry over to the "Delay" image state with no emitter, before going to the "Smoke" image state. Hope this helps, happy coding. :)

« Last Edit: July 03, 2024, 02:16:01 PM by Goth77 »

no, they are actually overlapping, the charge particle has a very short lifetime so any overlap caused in the way you described would be minuscule
i tested it with the added delay state and the emitter will still continue through that and into the smoke state and onward

no, they are actually overlapping, the charge particle has a very short lifetime so any overlap caused in the way you described would be minuscule
i tested it with the added delay state and the emitter will still continue through that and into the smoke state and onward
I see. post the entire image state code plz

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

stateName[1] = "Ready";
stateTransitionOnTriggerDown[1] = "Charge";
stateAllowImageChange[1] = true;
stateTransitionOnTimeout[1] = "Ready";
stateWaitForTimeout[1] = false;
stateTimeoutValue[1] = 0.2;

stateName[2] = "Fire";
stateTransitionOnTimeout[2] = "Reload";
stateTimeoutValue[2] = 0.04;
stateFire[2] = true;
stateAllowImageChange[2] = false;
stateScript[2] = "onFire";
stateWaitForTimeout[2] = true;
stateEmitter[2] = staticBeamFlashEmitter;
stateEmitterTime[2] = 0.05;
stateEmitterNode[2] = "muzzleNode";
stateSound[2] = noTimeFireSound;

stateName[3] = "Smoke";
stateTimeoutValue[3] = 0.4;
stateScript[3] = "onMisfire";
stateTransitionOnTimeout[3] = "Reload";
stateEmitter[3] = rocketLauncherSmokeEmitter;
stateEmitterTime[3] = 0.3;
stateEmitterNode[3] = "muzzleNode";
stateSound[3] = rocketFireSound;
stateWaitForTimeout[3] = true;

stateName[4] = "Reload";
stateTimeoutValue[4] = 1.0;
stateTransitionOnTimeout[4] = "Ready";
stateWaitForTimeout[4] = true;

stateName[5] = "Charge";
stateTimeoutValue[5] = 1.5;
stateScript[5] = "onBoltback";
stateTransitionOnTimeout[5] = "Fire";
stateTransitionOnTriggerUp[5] = "Smoke";
stateEmitter[5] = bigBangChargeEmitter;
stateEmitterTime[5] = 1.35;
stateEmitterNode[5] = "muzzleNode";
stateSound[5] = bigBangChargeSound;
stateWaitForTimeout[5] = false;

fixed. sorry I overlooked it the first time around. thanks for posting the full image code I was able to test it much easier.

Code: [Select]
stateWaitForTimeout[5] = true;

« Last Edit: July 03, 2024, 03:42:35 PM by Goth77 »

i know that waiting for timeout would work but i would like to be able to release the charge early

I mean technically you are releasing the charge early when you don't keep click held down through the duration of the charge state, but I think I understand what you mean. What you could try is making your weapon function more like the spear where you hold click down during the entirety of the charge until it reaches a "fully charged" state. Here is an example I wrote up for you:

Code: [Select]
stateName[0] = "Activate";
stateTimeoutValue[0] = 0.1;
stateTransitionOnTimeout[0] = "Ready";
stateSequence[0] = "ready";
stateSound[0] = weaponSwitchSound;

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

stateName[2]                    = "Charge";
stateTransitionOnTimeout[2] = "Armed";
stateTimeoutValue[2]            = 0.7;
stateWaitForTimeout[2] = false;
stateTransitionOnTriggerUp[2] = "AbortCharge";
stateScript[2]                  = "onCharge";
stateAllowImageChange[2]        = false;

stateName[3] = "AbortCharge";
stateTransitionOnTimeout[3] = "Ready";
stateTimeoutValue[3] = 0.3;
stateWaitForTimeout[3] = true;
stateScript[3] = "onAbortCharge";
stateAllowImageChange[3] = false;
stateEmitter[3] = rocketLauncherSmokeEmitter;
stateSound[3] = rocketFireSound;
stateEmitterTime[3] = 0.3;
stateEmitterNode[3] = "muzzleNode";

stateName[4] = "Armed";
stateTransitionOnTriggerUp[4] = "Fire";
stateAllowImageChange[4] = false;
stateEmitter[4] = bigBangChargeEmitter;
stateSound[4] = bigBangChargeSound;
stateEmitterTime[4] = 0.2;
stateEmitterNode[4] = "muzzleNode";

stateName[5] = "Fire";
stateTransitionOnTimeout[5] = "Ready";
stateTimeoutValue[5] = 0.5;
stateFire[5] = true;
stateSequence[5] = "fire";
stateScript[5] = "onFire";
stateWaitForTimeout[5] = true;
stateAllowImageChange[5] = false;
stateEmitter[5] = staticBeamFlashEmitter;
stateEmitterTime[5] = 0.05;
stateEmitterNode[5] = "muzzleNode";
stateSound[5] = noTimeFireSound;

I added your custom sfx and emitters into this code, but you'll probably want to adjust the timeout values and script callbacks since those are the same as the default spear. Let me know how it goes.

EDIT: as far as I'm aware there isn't a way to prematurely cancel an emitter on a weapon using the change state system by itself in this manner. the emitter will always finish until the emitter timeout. what you would do is use a script callback and mount an image to the player's muzzle node during the charge state (the charging emitter) and in the abort script callback you would delete said image then play the smoke emitter

« Last Edit: July 03, 2024, 05:10:07 PM by Goth77 »

what you would do is use a script callback and mount an image to the player's muzzle node during the charge state (the charging emitter) and in the abort script callback you would delete said image then play the smoke emitter
this is what i desire. how would one mount such an image to such a node

Okay so after further testing, here is a crude example of how to achieve the effect you are looking for. Again, you will need to modify this code to suit your weapons image names and the timings and such, but functionality wise this seems to work perfectly.

Code: [Select]
datablock ShapeBaseImageData(spearImage)
{
   shapeFile = "./gun.dts";
   emap = true;
   mountPoint = 0;
   offset = "0 0 0";
   correctMuzzleVector = true;
   className = "WeaponImage";
   item = spearItem;
   ammo = " ";
   projectile = spearProjectile;
   projectileType = Projectile;
   melee = false;
   armReady = true;
   doColorShift = true;
   colorShiftColor = "0.400 0.196 0 1.000";
   // Initial start up state
stateName[0] = "Activate";
stateTimeoutValue[0] = 0.1;
stateTransitionOnTimeout[0] = "Ready";
stateSequence[0] = "ready";
stateSound[0] = weaponSwitchSound;

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

stateName[2]                    = "Charge";
stateTransitionOnTimeout[2] = "Armed";
stateTimeoutValue[2]            = 0.7;
stateWaitForTimeout[2] = false;
stateTransitionOnTriggerUp[2] = "AbortCharge";
stateScript[2]                  = "onCharge";
stateAllowImageChange[2]        = false;
stateEmitter[2] = gunFlashEmitter;
stateSound[2] = bigBangChargeSound;
stateEmitterTime[2] = 0.7;
stateEmitterNode[2] = "muzzleNode";

stateName[3] = "AbortCharge";
stateTransitionOnTimeout[3] = "Ready";
stateTimeoutValue[3] = 0.3;
stateWaitForTimeout[3] = true;
stateScript[3] = "onAbortCharge";
stateAllowImageChange[3] = false;
//stateEmitter[3] = gunSmokeEmitter; - we don't need this since we are swapping images during this image states script callback
stateSound[3] = rocketFireSound;
stateEmitterTime[3] = 0.3;
stateEmitterNode[3] = "muzzleNode";

stateName[4] = "Armed";
stateTransitionOnTimeout[4] = "Armed";
stateTransitionOnTriggerUp[4] = "Fire";
stateAllowImageChange[4] = false;
stateEmitter[4] = gunFlashEmitter;
stateSound[4] = bigBangChargeFullSound; //this sfx will keep looping until release fire, probably want a different sound for this than initial charge sound
stateEmitterTime[4] = 0.2;
stateEmitterNode[4] = "muzzleNode";

stateName[5] = "Fire";
stateTransitionOnTimeout[5] = "Ready";
stateTimeoutValue[5] = 0.5;
stateFire[5] = true;
stateSequence[5] = "fire";
stateScript[5] = "onFire";
stateWaitForTimeout[5] = true;
stateAllowImageChange[5] = false;
stateEmitter[5] = gunFlashEmitter;
stateEmitterTime[5] = 0.05;
stateEmitterNode[5] = "muzzleNode";
stateSound[5] = noTimeFireSound;
};

datablock ShapeBaseImageData(AbortSmokeImage)
{
   // Basic Item properties
   shapeFile = "./gun.dts";
   emap = true;
   mountPoint = 0;
   offset = "0 0 0";
   correctMuzzleVector = true;
   className = "WeaponImage";
   // Projectile && Ammo.
   item = spearItem;
   ammo = " ";
   projectile = spearProjectile;
   projectileType = Projectile;
   melee = false;
   armReady = true;
   doColorShift = true;
   colorShiftColor = "0.400 0.196 0 1.000";
   // Initial start up state
stateName[0] = "Activate";
stateTimeoutValue[0] = 0.3;
stateTransitionOnTimeout[0] = "Done";
stateEmitter[0] = gunSmokeEmitter;
stateEmitterTime[0] = 0.3;
stateEmitterNode[0] = "muzzleNode";

stateName[1] = "Done";
stateTimeoutValue[1]    = 0.1;
stateScript[1]                  = "onDone";
};

function spearImage::onCharge(%this, %obj, %slot)
{
%obj.playthread(2, spearReady);
}

function spearImage::onAbortCharge(%this, %obj, %slot)
{
%obj.playthread(2, root);
//Swap to abort smoke image
%obj.mountImage(AbortSmokeImage,0);
}

function spearImage::onFire(%this, %obj, %slot)
{
%obj.playthread(2, spearThrow);
Parent::onFire(%this, %obj, %slot);
}

function AbortSmokeImage::onDone(%this, %obj, %slot)
{
//Swap back to original weapon
%obj.mountImage(SpearImage,0);
}

During the abort sequence, the weapon image changes to a duplicate image with only a smoking image state, and at the end of the abort images life, it swaps back to the original weapon image. This effectively (and deceptively, I might add) solves the emitter overlap issue.