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.
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.