Author Topic: Odd camera.setMode delay bug  (Read 410 times)

Issue: Electrocution event works; however, the client doesn't immediately switch to controlling their camera (which is in corpse mode, spying their player) until one second passes. After one second of "electrocution", it will immediately switch the client's control to their camera unless the electrocution period is over.

It should immediately switch the camera to corpse mode when electrocution starts, and switch back when electrocution ends.

Examples:
onActivate > Player > electrocute [5];
  • On activation, the electrocution colorswapping and zap plays, but the camera is not switched to corpse mode until one second later. It switches back to normal exactly when it should.


onActivate > Player > electrocute [1];
  • On first activation, the electrocution happens but the camera is not switched at all. On second activation, the camera immediately switches as electrocution starts, as it should. On third activation, it acts like first activation, and fourth like second.


Code:
Code: [Select]
registerOutputEvent("Player", "electrocute", "int 0 60", 1);

//odd bug where the corpse cam wont immediately switch unless one second of electrocution time passes
function Player::electrocute(%player, %time)
{
if (!isObject(%client = %player.client))
return;

%client.camera.setMode(Corpse, %player);
%client.setControlObject(%client.camera);

talk(%player SPC %time);
talk(%client.camera.mode SPC %client.camera.getControllingClient());
talk(%player.getControllingClient());
electrocute(%player, %time);
}


function electrocute(%player, %time)
{
if (!isObject(%client = %player.client))
return;

if (isEventPending(%player.electrocuteLoop))
cancel(%player.electrocuteLoop);
if (%time <= 0)
{
talk("resetting");
%client.applyBodyColors();
%client.camera.setMode(Observer);
%client.setControlObject(%player);
%client.isBeingElectrocuted = 0;
return;
}

%client.isBeingElectrocuted = 1;

%player.setNodeColor("ALL", "1 1 1 1");
%player.schedule(100, setNodeColor, "ALL", "0 0 0 1");
%player.schedule(200, setNodeColor, "ALL", "1 1 1 1");
%player.schedule(300, setNodeColor, "ALL", "0 0 0 1");
%player.schedule(400, setNodeColor, "ALL", "1 1 1 1");
%player.schedule(500, setNodeColor, "ALL", "0 0 0 1");
%player.schedule(600, setNodeColor, "ALL", "1 1 1 1");
%player.schedule(700, setNodeColor, "ALL", "0 0 0 1");
%player.schedule(800, setNodeColor, "ALL", "1 1 1 1");
%player.schedule(900, setNodeColor, "ALL", "0 0 0 1");

%player.playThread(2, plant);
%player.schedule(100, playThread, 2, plant);
%player.schedule(200, playThread, 2, plant);
%player.schedule(300, playThread, 2, plant);
%player.schedule(400, playThread, 2, plant);
%player.schedule(500, playThread, 2, plant);
%player.schedule(600, playThread, 2, plant);
%player.schedule(700, playThread, 2, plant);
%player.schedule(800, playThread, 2, plant);
%player.schedule(900, playThread, 2, plant);

%player.electrocuteLoop = schedule(1000, 0, electrocute, %player, %time - 1);

spawnRadioWaves(%player);
schedule(100, 0, spawnRadioWaves, %player);
schedule(200, 0, spawnRadioWaves, %player);
schedule(300, 0, spawnRadioWaves, %player);
schedule(400, 0, spawnRadioWaves, %player);
schedule(500, 0, spawnRadioWaves, %player);
schedule(600, 0, spawnRadioWaves, %player);
schedule(700, 0, spawnRadioWaves, %player);
schedule(800, 0, spawnRadioWaves, %player);
schedule(900, 0, spawnRadioWaves, %player);
}

function spawnRadioWaves(%player)
{
%pos = %player.getMuzzlePoint(2);
%scale = getWord(%player.getScale(), 2)*0.5+getRandom()*1.5;

%proj = new Projectile(){
datablock = radioWaveProjectile;
initialPosition = %pos;
initialVelocity = "0 0 0";
scale = %scale SPC %scale SPC %scale;
};
%proj.explode();
}

I think it has something to do with the player left clicking / triggering, if you change it from onActivate to onPlayerTouch and move the player away from the brick e.g. addVelocity, it'll do it properly 100% of the time.

Code: [Select]
if (isPackage(electrocuting))
deactivatePackage(electrocuting);

package electrocuting {

function Observer::onTrigger(%this, %obj, %trig, %state) {
%client = %obj.getControllingClient();

if (%client.isBeingElectrocuted)
return;

Parent::onTrigger(%this, %obj, %trig, %state);
}

};

activatePackage(electrocuting);

Packaging Observer::onTrigger seems to fix your issue.

ah, so for some reason observer ontrigger is getting called right after you click, leaving the "spy cam" mode. alright, thanks.

still doesnt explain the alternating situation, but as long as this fix works its not a big deal i guess. yet another quirk of torque hm

It sounds like you could put setMode on a schedule.
Code: [Select]
%client.camera.schedule(36,"setMode","Corpse",%player);That way it would change your camera after it has both left Player::electrocute and gone through Player::onTrigger.

At least I think that's what it would do.