Massassi Forums Logo

This is the static archive of the Massassi Forums. The forums are closed indefinitely. Thanks for all the memories!

You can also download Super Old Archived Message Boards from when Massassi first started.

"View" counts are as of the day the forums were archived, and will no longer increase.

ForumsCog Forum → Trigger causes cog to stall.
Trigger causes cog to stall.
2003-07-17, 3:15 PM #1
This is the weirdest problem I have ever come across. So bare with my descriptions etc. Unfortunatly you will be unable to test the cog without the rest of Team Battle. So if someone(s) thinks they know a reason but need to test the cog further I will need to upload Team Battle for them. (Will be about an 8mb download)

Anyways here goes:

The cog runs correctly the first 2 times or so. And then after running the roundend code, it calls ghost mode. Within ghost mode a trigger is sent to everyone to notify of a change to ky.3do (which is the ghost model)

Now normally, the trigger is sent and recieved correctly, and the ghostmode module continues to run. However, after the second round, after calling the trigger, the ghostmode module stops running after the trigger is sent. And the end of round module continues as if the ghostmode module just returned.

This also occurs on the spawned module which is called 3 seconds later. The first trigger causes the spawned module to return, and the roundend module continues.

But, triggers sent that are recieved outside of this cog do not cause this problem. (like the dismount trigger under the ghostmode module)

I have spent alot of time trying to define the player in different ways, trying to work out why its stopping etc. And short of re-writing that part of the cog to make it somehow different I'm not sure what to do.

It may be something really simple, or thats what I'm hoping.

Here is the cog, its got a few comments to show you whats happening alittle better.

Code:
#=======================================================================#
#
# Jedi Knight Cog Script
#
# gameplay.COG
#
# This cog controls all the gameplay scripting in Team Battle.
#
# [Hellcat]
#
# This Cog is Not supported by LucasArts Entertainment Co
#=======================================================================#
flags=0x240
#=======================================================================#

symbols

thing        player                             local                         

thing        sp_ct0                                                           
thing        sp_ct1                                                           
thing        sp_ct2                                                           
thing        sp_ct3                                                           
thing        sp_ct4                                                           
thing        sp_ct5                                                           
thing        sp_ct6                                                           
thing        sp_ct7                                                           

thing        sp_t0                                                            
thing        sp_t1                                                            
thing        sp_t2                                                            
thing        sp_t3                                                            
thing        sp_t4                                                            
thing        sp_t5                                                            
thing        sp_t6                                                            
thing        sp_t7                                                            

int          idp=0                              local                         

int          team=0                             local                         
int          playmdl=0                          local                         
int          shotgun=0                          local                         
int          rifle=0                            local                         
int          machine_gun=0                      local                         

int          round_time=300                                                   
int          timer=0                            local                         

int          ct=0                               local                         
int          ct2=0                              local                         
int          t=0                                local                         
int          t2=0                               local                         

model        CTpa=kyX0.3do                      local                         
model        CTpb=kyT0.3do                      local                         
model        CTpc=kyV0.3do                      local                         
model        CTpd=kyA19.3do                     local                         
model        CTpe=kyW0.3do                      local                         

model        Tpa=kyY0.3do                       local                         
model        Tpb=kyA17.3do                      local                         
model        Tpc=kyU0.3do                       local                         
model        Tpd=kyU0.3do                       local                         
model        Tpe=kyA18.3do                      local                         

model        neutral_mdl=ky.3do                 local                         

template     teleport_particles=+telesparks     local                         

message      trigger                                                          
message      timer                                                            
message      startup                                                          
message      newplayer                                                        
message      pulse                                                            
message      roundend                                                         
message      spawned                                                          
message      ghostmode                                                        
                                                    

end                                                                           

#=======================================================================#

code
trigger:

	if(GetSourceRef() == 55)
	{
		// Trigger to accept all info needed for respanwing etc
		team = GetParam(0);	
		playmdl = GetParam(1);	
	}

	else if(GetSourceRef() == 57)
	{
		// Trigger to accept all info needed for respawning etc
		shotgun = GetParam(0);	
		smg = GetParam(1);	
		rifle = GetParam(2);	
		machine_gun = GetParam(3);

		call spawned;
	}

	//Player model and team Syncranization
	else if(GetSourceRef() == 163)
	{
		SetThingCollideSize(player, 0.065000); 
		SetThingMoveSize(player, 0.065000);

		If(GetParam(0) == 1)
		{
			SetPlayerTeam(GetSenderRef(), 1);
			If(GetParam(1)==1) SetThingModel(GetSenderRef(), CTpa);
			If(GetParam(1)==2) SetThingModel(GetSenderRef(), CTpb);
			If(GetParam(1)==3) SetThingModel(GetSenderRef(), CTpc);
			If(GetParam(1)==4) SetThingModel(GetSenderRef(), CTpd);
			If(GetParam(1)==5) SetThingModel(GetSenderRef(), CTpe);
		}
		else If(GetParam(0) == 2)
		{
			SetPlayerTeam(GetSenderRef(), 2);
			If(GetParam(1)==1) SetThingModel(GetSenderRef(), Tpa);
			If(GetParam(1)==2) SetThingModel(GetSenderRef(), Tpb);
			If(GetParam(1)==3) SetThingModel(GetSenderRef(), Tpc);
			If(GetParam(1)==4) SetThingModel(GetSenderRef(), Tpd);
			If(GetParam(1)==5) SetThingModel(GetSenderRef(), Tpe);
		}
		else
		{
			// First make the player a transperent 3do
			SetThingModel(GetSenderRef(), neutral_mdl);	

			// Now make him have no collide
			SetThingCollideSize(GetSenderRef(), 0.00001);
			SetThingMoveSize(GetSenderRef(), 0.065000);	
		}
	}

	else if(GetSourceRef() == 58)
	{
		If(GetParam(0) == 1)
		{
			If(GetParam(1) == 1)
			{
				ct = ct + 1;
				ct2 = ct2 + 1;
			}
			else
			{
				ct = ct - 1;
			}
		}
		else if(GetParam(0) == 2)
		{
			If(GetParam(1) == 1)
			{
				t = t + 1;
				t2 = t2 + 1;
			}
			else
			{
				t = t - 1;
			}
		}

		//THIS IS PRINTED
		Print("PASSED!!!!!!!!!!!!!!!!!!!");
	}

	else if(GetSourceRef() == 59)
	{
		timer = GetParam(0);
		PrintInt(timer);
	}

	else if(GetSourceRef() == 60) //Recieve host's round end trigger
	{
		ct = GetParam(0);
		t = GetParam(1);
		call roundend;
	}

	else if(GetSourceRef() == 1688)
	{
		victor = GetSenderRef();
		//sleep(5.0);
		Print("Points gained for winning the round!!!");
		SetPlayerScore(victor, GetPlayerScore(victor) + GetParam(0));
		SyncScores();
	}

return;

#=======================================================================#

timer:


return;

#=======================================================================#

startup:

	player = GetLocalPlayerThing();
	
	// Sleep so then we dont interupt the loading process.
	Sleep(0.25);

	// Lets start ghost mode, thats what the player starts in
	// call ghostmode;
	
	// Check to see what the rountime is set to in the level cog.
	timer=round_time;

	// If we're the host then start the clock. We let the server control as much as possible. Also remove ff
	If(IsServer()) 
	{
		SetPulse(1);
		SetMultiModeFlags(0x3);
	}
return;

#=======================================================================#

newplayer:

	player = GetLocalPlayerThing();

	// Sleep so then we dont interupt the loading process.
	Sleep(0.25);
	
	// Lets start ghost mode, thats what the player starts in after dying
	call ghostmode;

return;

#=======================================================================#

pulse:
	//Count down the timer
	timer = timer - 1;
	SendTrigger(-1, 59, timer, 0, 0, 0);

	//Check to see if one team is dead or the timer ran out:
	If(ct == 0 || t == 0 || timer == 0)
	{

		//Check to see if the team is acctually all dead or if there are
		//none of the other team in the game. But if there are none in 
		//the game and we get time 0 then we want to go to the next round
		If(ct == 0 && ct2 == 0 && timer !=0 && t == t2) return;
		If(t == 0 && t2 == 0 && timer !=0 && ct == ct2) return;
		
		//Set the pulse back to 0 so then we dont count down.
		setpulse(0);

		//Server sends round winning info to all players
		SendTrigger(-1, 60, ct, t, 0, 0);
	}

return;

#=======================================================================#

roundend:

	//End of the round code
	If(ct == 0 && t == 0) Print("Round Draw");

	//If theres no special ops left
	If(ct == 0) 
	{
		Print("Terrorists Win, Special Operations are eliminated.");
		//if(GetThingTeam(player) == 2) SendTrigger(-1, 1688, 2, 0, 0, 0);
	}

	//If all the terrorists are dead
	If(t == 0 && timer != 0) 
	{
		Print("Special Operations Win, terrorists eliminated.");
		//if(GetThingTeam(player) == 1) SendTrigger(-1, 1688, 2, 0, 0, 0);
	}
	
	// Time is 0 and the hostages are still in trouble??	
	If(timer == 0) Print("Terrorists Win, hostages have not been rescued");

	//Set the time back to our original time
	timer=round_time;

	//Lets tell the user whats happening
	Print("End of Round!");
	Print("Next Round will start in 3 seconds!");

	//If the player is still choosing their team or if their in ghostmode then make sure they dont do any of the following
	If(team == 0)
	{
		//Set all the essentials back to 0
		ct = 0;
		t = 0;
		ct2 = 0;
		t2 = 0;

		//If we're the server set the timer going again
		If(IsServer()) SetPulse(1);
	
		//return so we dont end up doing everything again.
		return;	
	}

	//Call the ghost mode
	call ghostmode;

	//Sleep 3 seconds before respawning players
	Sleep(3.0);

	//Set all the essentials back to 0
	ct = 0;
	t = 0;
	ct2 = 0;
	t2 = 0;

	//Set the spawned to 0 to allow players who have died this round spawn again
	spawned = 0;

	//Call the player to spawn for next round
	call spawned;

	//Server goes back to its counting position
	If(IsServer()) SetPulse(1);

return;

#=======================================================================#

spawned:

	player = GetLocalPlayerThing();

	//Player can only spawn in the first 60secs, and make sure he doesnt try to re-join a team and spawn.
	If((round_time - timer) > 60 || spawned == 1)
	{
		Print("You will spawn in the next round.(60 seconds has passed, or you have died this round.)");
		return;
	}

	//Set spawned to 1 so players cant just re-spawn
	spawned = 1;

	//Inform player
	Print("Spawned");

	//Stop the player so he doesnt have speed from ghost mode
	StopThing(player);

	//Make the player NOT able to float
	SetPhysicsFlags(player, 0x1);
	ClearPhysicsFlags(player, 0x2000);

	//Print("CHECKING!!!!!!!!!!!!!!!!!!!");

	// Send a trigger to say we have joined
	SendTrigger(-1, 58, team, 1, 0, 0); 

	//Print("PASSED!!!!!!!!!!!!!!!!!!!");
	
	// Give pistol and knife to the player (80 pistol shots)
   	SetInv(player, 1, 1.0);
   	SetInv(player, 2, 1.0);
   	SetInv(player, 151, 80.0);

	//If the num is 0, then they didnt buy
	If(shotgun != 0) 
	{
		SetInv(player, 3, 1.0);
		SetInv(player, 152, 32.0);
	}
   	If(smg != 0)
	{
		SetInv(player, 4, 1.0);
		SetInv(player, 4, 120.0);
	}
   	If(rifle != 0) 
	{
		SetInv(player, 5, 1.0);
		SetInv(player, 12, 120.0);
	}
   	If(machine_gun != 0) 
	{
		SetInv(player, 6, 1.0);
		SetInv(player, 12, 250.0);
	}

	//Give the their grenades, currently not implemented
   	// If(playmdl == 1 || playmdl == 2 || playmdl == 3 || playmdl == 4 || playmdl == 5) SetInv(player, 7, 1.0);
   	// If(playmdl == 1 || playmdl == 2 || playmdl == 3 || playmdl == 4 || playmdl == 5) SetInv(player, 8, 1.0);

	//Cant change teams ingame, only in respawn mode. May change in future. Also 10 (lightsaber) will indicate a host only bot control.
   	SetInv(player, 9, 1.0);
   	SetInv(player, 10, 0.0);

	// Now set the respawn point by doing a random number. 
	//In later version the host may set these for the player
	//Need to fix the random so it evenly produces collisions, so we do this budgetly
	idp = Rand() * 8;
	If (idp <= 1) idp = 1;
	else if (idp <= 2) idp = 2;
	else if (idp <= 3) idp = 3;
	else if (idp <= 4) idp = 4;
	else if (idp <= 5) idp = 5;
	else if (idp <= 6) idp = 6;
	else if (idp <= 7) idp = 7;
	else if (idp <= 8) idp = 0;


	//Now lets spawn them. Set their player model and team. 
	//Use teleport player as a sneaky trick as spawning=)
	If(team == 1)
	{
		//Because we are only running locally. Send trigger to all the players
		SendTrigger(-1, 163, team, playmdl, 0, 0); 
       	TeleportThing(player, sp_ct0[idp]);			
	}
	else If(team == 2)
	{
		//Because we are only running locally. Send trigger to all the players
		SendTrigger(-1, 163, team, playmdl, 0, 0); 
	       TeleportThing(player, sp_t0[idp]);	
	}

	//Set up player speeds etc.
	If(playmdl == 1)
	{
		SetInv(player, 60, 100);
		ParseArg(player, "maxthrust=1.25 jumpspeed=1.25"); 
		 
		//Give player Night vision
		ChangeInv(player, 41, 1.0);
      		SetInvAvailable(player, 41, 1);

		//Give him battery charge
		ChangeInv(player, 13, 100.0);
		
	}
	If(playmdl == 2)
	{
		SetInv(player, 60, 200);
		ParseArg(player, "maxthrust=1.0 jumpspeed=1.0"); 
	}
	If(playmdl == 3)
	{
		SetInv(player, 60, 120);
		ParseArg(player, "maxthrust=1.15 jumpspeed=1.15"); 
	}
	If(playmdl == 4)
	{
		SetInv(player, 60, 80);
		ParseArg(player, "maxthrust=1.3 jumpspeed=1.3");
	}
	If(playmdl == 5)
	{
		SetInv(player, 60, 200);
		ParseArg(player, "maxthrust=0.9 jumpspeed=0.9");
		 
		//Give player Night vision
		ChangeInv(player, 41, 1.0);
      		SetInvAvailable(player, 41, 1);

		//Give him battery charge
		ChangeInv(player, 13, 100.0);
	}

	// Do respawn effects - temporaraly disabled
	//dummy = CreateThingAtPos(teleport_particles, GetThingSector(player), GetThingPos(player), '0 0 0');
	// dummy = PlaySoundThing(teleportsnd, player, 1.0, -1, -1, 0x180);

	//Set our wait
	SetFireWait(player, -1);
	SetMountWait(player, 0);
	SetCurInvWeapon(player, 0);
	//SelectWeapon(player, AutoSelectWeapon(player, 1));
	SelectWeapon(player, 2);

return;

#=======================================================================#

ghostmode:

	player = GetLocalPlayerThing();

	Print("Ghost mode");

	//THIS IS PRINTED
	Print("CHECKING!!!!!!!!!!!!!!!!!!!");

	//Send to host that we died.
	SendTrigger(-1, 58, team, 0, 0, 0); 
	//THIS IS NOT PRINTED

	Print("PASSED!!!!!!!!!!!!!!!!!!!");

	//Change players model and movesize etc.
	SendTrigger(-1, 163, 0, 0, 0, 0); 

	//Sendtrigger to dismount weapon (Only if we have one out I spose... let the weapon cogs handle that)
	SendTrigger(player, 62, 0, 0, 0, 0);

	// Set guns. Give them ability to change teams
   	SetInv(player, 1, 0.0);
   	SetInv(player, 2, 0.0);
   	SetInv(player, 3, 0.0);
   	SetInv(player, 4, 0.0);
   	SetInv(player, 5, 0.0);
   	SetInv(player, 6, 0.0);
   	SetInv(player, 7, 0.0);
   	SetInv(player, 8, 0.0);
   	SetInv(player, 9, 1.0);
   	SetInv(player, 10, 0.0);

	//Make the player able to float - flying mode
	ClearPhysicsFlags(player, 0x1);
	SetPhysicsFlags(player, 0x2000);

return;

#=======================================================================#

end


If anyone needs anymore detail please dont hesitate to post!!

Thanks for any posts.

------------------
Team Battle.
Team Battle.
2003-07-17, 7:45 PM #2
Some errors you have
1) you cant have a variable named timer (that is a message name)
2) you are missing variables for spawned, smg, and victor
3) your last 3 messages in the symbols section should not be there. (i don't know if they cause a problem but they don't need to be there)
4) parsec has a problem with SetThingCollideSize so it may be unstable somehow.

Those are the only errors caught by parsec, but without the mod I can't test it to see if it worked. If you can upload it somewhere I could play with the cog some more and get back to you when it works.

------------------
Sam: "Sir we can't call it 'The Enterprise'"
Jack: "Why not!"
Sam: "Sir we can't call it 'The Enterprise'"
Jack: "Why not!"
2003-07-17, 9:47 PM #3
None of those errors really matter. (Except the first one, but it didnt fix it.)

If no other people have an opinion then I may send it to you.

------------------
Team Battle.
Team Battle.
2003-07-18, 8:14 AM #4
i may have an answer for you and a way to fix your cog.

i made this cog to test some different ways to send triggers.
Code:
######
# Jedi Knight Cog Script  (JK)
#-----
# TRIGCALL_TST.COG
#-----
# Written By DSLS_DeathSythe
# This COG is NOT supported by LucasArts Entertainment Co.
######
flags=0x240
symbols
#-----
message     startup
message     activated
message     timer
message     trigger

thing       player=-1     local

thing       console=-1

int         test_mode=0
flex        delay=0.1

sound       act_snd=-1

int         first_trig=1
int         second_trig=2
int         third_trig=3
int         fourth_trig=4
int         fifth_trig=5
#-----
end
#=====
code
#-----
startup:
	player = GetLocalPlayerThing();
return;
#-----
activated:
	PlaySoundThing(act_snd, console, 1.0, -1, -1, 0x0);
	SendTrigger(-1, first_trig, 0, 0, 0, 0);
return;
#-----
timer:
	if(GetSenderID() == 1)
		{
		Print("First Timer DONE!!!");
		SendTrigger(-1, second_trig, 0, 0, 0, 0);
		return;
		}
	else
	if(GetSenderID() == 2)
		{
		Print("Second Timer DONE!!!");
		SendTrigger(-1, third_trig, 0, 0, 0, 0);
		return;
		}
	else
	if(GetSenderID() == 3)
		{
		Print("Third Timer DONE!!!");
		SendTrigger(-1, fourth_trig, 0, 0, 0, 0);
		return;
		}
	else
	if(GetSenderID() == 4)
		{
		Print("Fourth Timer DONE!!!");
		SendTrigger(-1, fifth_trig, 0, 0, 0, 0);
		return;
		}
return;
#-----
trigger:
	if(GetSourceRef() == first_trig)
		{
		Print("Got FIRST Trig (1)");
		if(test_mode == 1)
			{
			Sleep(delay);
			}
		Call first_mode;
		return;
		}
	else
	if(GetSourceRef() == second_trig)
		{
		Print("Got SECOND Trig (2)");
		if(test_mode == 1)
			{
			Sleep(delay);
			}
		Call second_mode;
		return;
		}
	else
	if(GetSourceRef() == third_trig)
		{
		Print("Got THIRD Trig (3)");
		if(test_mode == 1)
			{
			Sleep(delay);
			}
		Call third_mode;
		return;
		}
	else
	if(GetSourceRef() == fourth_trig)
		{
		Print("Got FOURTH Trig (4)");
		if(test_mode == 1)
			{
			Sleep(delay);
			}
		Call fourth_mode;
		return;
		}
	else
	if(GetSourceRef() == fifth_trig)
		{
		Print("Got FIFTH Trig (5)");
		if(test_mode == 1)
			{
			Sleep(delay);
			}
		Call fifth_mode;
		return;
		}
return;
#-----
first_mode:
	Print("FIRST mode CALLED...");

	if(test_mode == 0)
		{
		SendTrigger(-1, second_trig, 0, 0, 0, 0);
		return;
		}
	else
	if(test_mode == 1)
		{
		Sleep(delay);
		SendTrigger(-1, second_trig, 0, 0, 0, 0);
		return;
		}
	SetTimerEx(delay, 1, 0, 0);
return;
#-----
second_mode:
	Print("SECOND mode CALLED...");

	if(test_mode == 0)
		{
		SendTrigger(-1, third_trig, 0, 0, 0, 0);
		return;
		}
	else
	if(test_mode == 1)
		{
		Sleep(delay);
		SendTrigger(-1, third_trig, 0, 0, 0, 0);
		return;
		}
	SetTimerEx(delay, 2, 0, 0);
return;
#-----
third_mode:
	Print("THIRD mode CALLED...");

	if(test_mode == 0)
		{
		SendTrigger(-1, fourth_trig, 0, 0, 0, 0);
		return;
		}
	else
	if(test_mode == 1)
		{
		Sleep(delay);
		SendTrigger(-1, fourth_trig, 0, 0, 0, 0);
		return;
		}
	SetTimerEx(delay, 3, 0, 0);
return;
#-----
fourth_mode:
	Print("FOURTH mode CALLED...");

	if(test_mode == 0)
		{
		SendTrigger(-1, fifth_trig, 0, 0, 0, 0);
		return;
		}
	else
	if(test_mode == 1)
		{
		Sleep(delay);
		SendTrigger(-1, fifth_trig, 0, 0, 0, 0);
		return;
		}
	SetTimerEx(delay, 4, 0, 0);
return;
#-----
fifth_mode:
	Print("FIFTH mode CALLED...");
	Print("All TRIGGERs done...");
return;
######
end

its a simple cog that has three test modes.
test_mode=0 tests just sending the triggers and calling a message and sending another trigger.
test_mode=1 test putting a sleep delay in between sending the trigger and calling the message.
test_mode=2 tests that when the trigger is recived it calls the message and the message sets a delay by a timerEx and that timer sends the next trigger.

heres the results of the testing i did:

test_mode=0 - the cog would only go up to where it says "Got THIRD Trig (3)" and would never do more no matter how may times i activated the console.

test_mode=1 - the cog would go up to where its says "Got THIRD Trig (3)" the first time it was activated, and any other time that it was activated it would only go to "Got FIRST Trig (1)"
and would never again do any more.

test_mode=2 - the cog would succsesfully go all the way to "All TRIGGERs done..." every time.

so for some weird reason cogs have a hard time sending triggers from a called message or something like that.
you can test my cog too and see if you get the same results if you want.

i ran into this problem or something like it when i was making my jk chess mod. all the cogs i used in that had flags=0x240 and sent triggers between themselves to communicate. my first few tries to get it to work the cogs either stalled or didnt work. so i started using SetTimerEx when ever i wanted to send a trigger. that seemed to fix the problem for me but it slowed things down a very tiny bit.

so maybe if you used SetTimerEx before you send each trigger it might fix it.

hope some of that info was helpful to you, good luck.

------------------
Famous last words - "It seemed like a good idea at the time."
Famous last words - "It seemed like a good idea at the time."
2003-07-18, 9:23 AM #5
That was a good idea deathsythe! I can't believe I forgot to mention adding a timer before the trigger. I must be slipping [http://forums.massassi.net/html/wink.gif]

------------------
Sam: "Sir we can't call it 'The Enterprise'"
Jack: "Why not!"

[This message has been edited by SG-fan (edited July 18, 2003).]
Sam: "Sir we can't call it 'The Enterprise'"
Jack: "Why not!"
2003-07-18, 3:55 PM #6
Thanks, I never really thought of putting a timer in. I will see if that fixes it later on today.

Btw I'm glad its not just my retarded cog not working, I was begining to believe jk had this thing for me...

------------------
Team Battle.
Team Battle.
2003-07-18, 4:49 PM #7
The weirdness gets deeper. I decided before fixing it up I would remove that sleep in the roundend module... and so I set up a timer. And now the whole cog works... so yeah... I dont get it.

All I know is it works, so thanks very much guys!!

------------------
Team Battle.
Team Battle.
2003-07-18, 4:51 PM #8
The player's thing number doesn't change, no need to reassign on newplayer.

This is really an interesting problem. I'll do some testing and post a little later.

------------------
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
2003-07-18, 5:23 PM #9
good to hear you got it to work Hellcat.

did anyone else try out my cog? i was wondering if everybody gets the same results i got, or if its just on my computer. its very strange that this happens.

if you come up with any reasons for this SM id very much like to hear about it.

------------------
Famous last words - "It seemed like a good idea at the time."
Famous last words - "It seemed like a good idea at the time."
2003-07-18, 5:31 PM #10
Aha! It's a thread problem. Because when you call SendTrigger(), a new thread is immediately created and run - the current thread is paused. So in a situation where the trigger message calls a message to send another trigger, you have an endless loop.

Try out this hotkeyed example:
Code:
# hotkey.cog
#
# Test hotkey script.
#
# [SM]
#==============================================================#
symbols

int       threads=0   local

message   activated
message   trigger

end
#==============================================================#
code
#------------------------------------------------------
activated:
	threads = threads + 1;
	jkStringClear();
	jkStringConcatAsciiString("Activated: Sending a Trigger. Thread: ");
	jkStringConcatInt(threads);
	jkStringOutput(-1, -1);
	Sleep(2);
	SendTrigger(-1, 33, 0, 0, 0, 0);
	Print("Activated: Message Finished.");
	threads = threads - 1;

Return;
#------------------------------------------------------
trigger:
	if(GetSourceRef() != 33) Return;
	threads = threads + 1;
	jkStringClear();
	jkStringConcatAsciiString("Trigger: Received a Trigger. Thread: ");
	jkStringConcatInt(threads);
	jkStringOutput(-1, -1);
	Sleep(2);
	call trigsend;
	Print("Trigger: Message Finished.");
	threads = threads - 1;

Return;
#------------------------------------------------------
trigsend:
	threads = threads + 1;
	jkStringClear();
	jkStringConcatAsciiString("Custom: Sending a Trigger. Thread: ");
	jkStringConcatInt(threads);
	jkStringOutput(-1, -1);
	Sleep(2);
	SendTrigger(-1, 33, 0, 0, 0, 0);
	Print("Custom: Message Finished.");
	threads = threads - 1;

Return;
#------------------------------------------------------
end


When I run this, I'm allowed six threads. After six threads, no more threads are created - the custom message trigsend cannot be called. Also, the trigger message is the only one that is allowed to finish. The activated and trigsend threads are both paused - waiting to resume.

My concept of threads still isn't perfect. Normally, a thread can be created for a message and slept up to four times. So why are there six threads in this example? It might be that calling custom messages doesn't count as a thread, but then when the sixth thread runs, why can't the message call be made?

So I suspect it's slightly more complicated than just a certain number of allowed threads - there may be different types or something...

Anyways, you'll need to fix your code to use timers. I think even if you use a delay of 0 for a timerEx, the current thread will finish and return before the timer event is run.

------------------
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
2003-07-18, 5:55 PM #11
I dunno.

Are you sure its not something to do with the sleep's combined with triggers? Cause all my problems went away when I got rid of the sleep.

------------------
Team Battle.
Team Battle.
2003-07-18, 10:00 PM #12
The only reason the sleeps are in there is so you can read the text and make sense of it - it goes the same way without them.

You got rid of Sleep() and used timers instead, right? If you're using a timer thread to send the trigger then you won't have the problem.

------------------
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
2003-07-18, 10:11 PM #13
I'm not sure what you mean. So I will post my cog that is now working.

Code:
#=======================================================================#
flags=0x240
#=======================================================================#

symbols

thing        player                             local                         

thing        sp_ct0                                                           
thing        sp_ct1                                                           
thing        sp_ct2                                                           
thing        sp_ct3                                                           
thing        sp_ct4                                                           
thing        sp_ct5                                                           
thing        sp_ct6                                                           
thing        sp_ct7                                                           

thing        sp_t0                                                            
thing        sp_t1                                                            
thing        sp_t2                                                            
thing        sp_t3                                                            
thing        sp_t4                                                            
thing        sp_t5                                                            
thing        sp_t6                                                            
thing        sp_t7                                                            

int          idp=0                              local                         

int          team=0                             local                         
int          playmdl=0                          local                         
int          shotgun=0                          local                         
int          rifle=0                            local                         
int          machine_gun=0                      local                         

int          round_time=300                                                   
int          roundtimer=0                            local                         

int          ct=0                               local                         
int          ct2=0                              local                         
int          t=0                                local                         
int          t2=0                               local                         

model        CTpa=kyX0.3do                      local                         
model        CTpb=kyT0.3do                      local                         
model        CTpc=kyV0.3do                      local                         
model        CTpd=kyA19.3do                     local                         
model        CTpe=kyW0.3do                      local                         

model        Tpa=kyY0.3do                       local                         
model        Tpb=kyA17.3do                      local                         
model        Tpc=kyU0.3do                       local                         
model        Tpd=kyU0.3do                       local                         
model        Tpe=kyA18.3do                      local                         

model        neutral_mdl=ky.3do                 local                         

template     teleport_particles=+telesparks     local                         

message      trigger                                                          
message      timer                                                            
message      startup                                                          
message      newplayer                                                        
message      pulse                                                            
                                                    
                                                    

end                                                                           

#=======================================================================#

code
trigger:

	if(GetSourceRef() == 55)
	{
		// Trigger to accept all info needed for respanwing etc
		team = GetParam(0);	
		playmdl = GetParam(1);	
	}

	else if(GetSourceRef() == 57)
	{
		// Trigger to accept all info needed for respawning etc
		shotgun = GetParam(0);	
		smg = GetParam(1);	
		rifle = GetParam(2);	
		machine_gun = GetParam(3);

		call spawned;
	}

	//Player model and team Syncranization
	else if(GetSourceRef() == 163)
	{
		SetThingCollideSize(player, 0.065000); 
		SetThingMoveSize(player, 0.065000);

		If(GetParam(0) == 1)
		{
			SetPlayerTeam(GetSenderRef(), 1);
			If(GetParam(1)==1) SetThingModel(GetSenderRef(), CTpa);
			If(GetParam(1)==2) SetThingModel(GetSenderRef(), CTpb);
			If(GetParam(1)==3) SetThingModel(GetSenderRef(), CTpc);
			If(GetParam(1)==4) SetThingModel(GetSenderRef(), CTpd);
			If(GetParam(1)==5) SetThingModel(GetSenderRef(), CTpe);
		}
		else If(GetParam(0) == 2)
		{
			SetPlayerTeam(GetSenderRef(), 2);
			If(GetParam(1)==1) SetThingModel(GetSenderRef(), Tpa);
			If(GetParam(1)==2) SetThingModel(GetSenderRef(), Tpb);
			If(GetParam(1)==3) SetThingModel(GetSenderRef(), Tpc);
			If(GetParam(1)==4) SetThingModel(GetSenderRef(), Tpd);
			If(GetParam(1)==5) SetThingModel(GetSenderRef(), Tpe);
		}
		else
		{
			// First make the player a transperent 3do
			SetThingModel(GetSenderRef(), neutral_mdl);	

			// Now make him have no collide
			SetThingCollideSize(GetSenderRef(), 0.00001);
			SetThingMoveSize(GetSenderRef(), 0.065000);	
		}
	}

	else if(GetSourceRef() == 58)
	{
		If(GetParam(0) == 1)
		{
			If(GetParam(1) == 1)
			{
				ct = ct + 1;
				ct2 = ct2 + 1;
			}
			else
			{
				ct = ct - 1;
			}
		}
		else if(GetParam(0) == 2)
		{
			If(GetParam(1) == 1)
			{
				t = t + 1;
				t2 = t2 + 1;
			}
			else
			{
				t = t - 1;
			}
		}
	}

	else if(GetSourceRef() == 59)
	{
		roundtimer = GetParam(0);
		PrintInt(roundtimer);
	}

	else if(GetSourceRef() == 60) //Recieve host's round end trigger
	{
		ct = GetParam(0);
		t = GetParam(1);
		call roundend;
	}

	else if(GetSourceRef() == 1688)
	{
		victor = GetSenderRef();
		//sleep(5.0);
		Print("Points gained for winning the round!!!");
		SetPlayerScore(victor, GetPlayerScore(victor) + GetParam(0));
		SyncScores();
	}

return;

#=======================================================================#

timer:

	if(GetSenderID() == 1) 
	{
		//Set all the essentials back to 0
		ct = 0;
		t = 0;
		ct2 = 0;
		t2 = 0;

		//Set the spawned to 0 to allow players who have died this round spawn again
		spawned_round = 0;

		//Call the player to spawn for next round
		call spawned;

		//Server goes back to its counting position
		If(IsServer()) SetPulse(1);
	}
return;

#=======================================================================#

startup:

	player = GetLocalPlayerThing();
	
	// Sleep so then we dont interupt the loading process.
	Sleep(0.25);

	// Lets start ghost mode, thats what the player starts in
	// call ghostmode;
	
	// Check to see what the rountime is set to in the level cog.
	roundtimer=round_time;

	// If we're the host then start the clock. We let the server control as much as possible. Also remove ff
	If(IsServer()) 
	{
		SetPulse(1);
		SetMultiModeFlags(0x3);
	}
return;

#=======================================================================#

newplayer:

	player = GetLocalPlayerThing();

	// Sleep so then we dont interupt the loading process.
	Sleep(0.25);
	
	// Lets start ghost mode, thats what the player starts in after dying
	call ghostmode;

return;

#=======================================================================#

pulse:
	//Count down the timer
	roundtimer = roundtimer - 1;
	SendTrigger(-1, 59, roundtimer, 0, 0, 0);

	//Check to see if one team is dead or the timer ran out:
	If(ct == 0 || t == 0 || roundtimer == 0)
	{

		//Check to see if the team is acctually all dead or if there are
		//none of the other team in the game. But if there are none in 
		//the game and we get time 0 then we want to go to the next round
		If(ct == 0 && ct2 == 0 && roundtimer !=0 && t == t2) return;
		If(t == 0 && t2 == 0 && roundtimer !=0 && ct == ct2) return;
		
		//Set the pulse back to 0 so then we dont count down.
		setpulse(0);

		//Server sends round winning info to all players
		SendTrigger(-1, 60, ct, t, 0, 0);
	}

return;

#=======================================================================#

roundend:

	//End of the round code
	If(ct == 0 && t == 0) Print("Round Draw");

	//If theres no special ops left
	If(ct == 0) 
	{
		Print("Terrorists Win, Special Operations are eliminated.");
		//if(GetThingTeam(player) == 2) SendTrigger(-1, 1688, 2, 0, 0, 0);
	}

	//If all the terrorists are dead
	If(t == 0 && roundtimer != 0) 
	{
		Print("Special Operations Win, terrorists eliminated.");
		//if(GetThingTeam(player) == 1) SendTrigger(-1, 1688, 2, 0, 0, 0);
	}
	
	// Time is 0 and the hostages are still in trouble??	
	If(roundtimer == 0) Print("Terrorists Win, hostages have not been rescued");

	//Set the time back to our original time
	roundtimer=round_time;

	//Lets tell the user whats happening
	Print("End of Round!");
	Print("Next Round will start in 3 seconds!");

	//If the player is still choosing their team or if their in ghostmode then make sure they dont do any of the following
	If(team == 0)
	{
		//Set all the essentials back to 0
		ct = 0;
		t = 0;
		ct2 = 0;
		t2 = 0;

		//If we're the server set the timer going again
		If(IsServer()) SetPulse(1);
	
		//return so we dont end up doing everything again.
		return;	
	}

	//Call the ghost mode
	call ghostmode;

	//Sleep 3 seconds before respawning players
	SetTimerEx(3, 1, 0, 0); 

return;

#=======================================================================#

spawned:

	player = GetLocalPlayerThing();

	//Player can only spawn in the first 60secs, and make sure he doesnt try to re-join a team and spawn.
	If((round_time - roundtimer) > 60 || spawned_round == 1)
	{
		Print("You will spawn in the next round.(60 seconds has passed, or you have died this round.)");
		if(GetInv(jkGetLocalPlayer(), 1) == 1) call ghostmode;
		return;
	}

	//Set spawned to 1 so players cant just re-spawn
	spawned_round = 1;

	//Inform player
	Print("Spawned");

	//Stop the player so he doesnt have speed from ghost mode
	StopThing(player);

	//Make the player NOT able to float
	SetPhysicsFlags(player, 0x1);
	ClearPhysicsFlags(player, 0x2000);

	// Send a trigger to say we have joined
	SendTrigger(-1, 58, team, 1, 0, 0); 
	
	// Give pistol and knife to the player (80 pistol shots)
   	SetInv(player, 1, 1.0);
   	SetInv(player, 2, 1.0);
   	SetInv(player, 151, 80.0);

	//If the num is 0, then they didnt buy
	If(shotgun != 0) 
	{
		SetInv(player, 3, 1.0);
		SetInv(player, 152, 32.0);
	}
   	If(smg != 0)
	{
		SetInv(player, 4, 1.0);
		SetInv(player, 4, 120.0);
	}
   	If(rifle != 0) 
	{
		SetInv(player, 5, 1.0);
		SetInv(player, 12, 120.0);
	}
   	If(machine_gun != 0) 
	{
		SetInv(player, 6, 1.0);
		SetInv(player, 12, 250.0);
	}

	//Give the their grenades, currently not implemented
   	// If(playmdl == 1 || playmdl == 2 || playmdl == 3 || playmdl == 4 || playmdl == 5) SetInv(player, 7, 1.0);
   	// If(playmdl == 1 || playmdl == 2 || playmdl == 3 || playmdl == 4 || playmdl == 5) SetInv(player, 8, 1.0);

	//Cant change teams ingame, only in respawn mode. May change in future. Also 10 (lightsaber) will indicate a host only bot control.
   	SetInv(player, 9, 1.0);
   	SetInv(player, 10, 0.0);

	// Now set the respawn point by doing a random number. 
	//In later version the host may set these for the player
	//Need to fix the random so it evenly produces collisions, so we do this budgetly
	idp = Rand() * 8;
	If (idp <= 1) idp = 1;
	else if (idp <= 2) idp = 2;
	else if (idp <= 3) idp = 3;
	else if (idp <= 4) idp = 4;
	else if (idp <= 5) idp = 5;
	else if (idp <= 6) idp = 6;
	else if (idp <= 7) idp = 7;
	else if (idp <= 8) idp = 0;


	//Now lets spawn them. Set their player model and team. 
	//Use teleport player as a sneaky trick as spawning=)
	If(team == 1)
	{
		//Because we are only running locally. Send trigger to all the players
		SendTrigger(-1, 163, team, playmdl, 0, 0); 
       	TeleportThing(player, sp_ct0[idp]);			
	}
	else If(team == 2)
	{
		//Because we are only running locally. Send trigger to all the players
		SendTrigger(-1, 163, team, playmdl, 0, 0); 
	       TeleportThing(player, sp_t0[idp]);	
	}

	//Set up player speeds etc.
	If(playmdl == 1)
	{
		SetInv(player, 60, 100);
		ParseArg(player, "maxthrust=1.25 jumpspeed=1.25"); 
		 
		//Give player Night vision
		ChangeInv(player, 41, 1.0);
      		SetInvAvailable(player, 41, 1);

		//Give him battery charge
		ChangeInv(player, 13, 100.0);
		
	}
	If(playmdl == 2)
	{
		SetInv(player, 60, 200);
		ParseArg(player, "maxthrust=1.0 jumpspeed=1.0"); 
	}
	If(playmdl == 3)
	{
		SetInv(player, 60, 120);
		ParseArg(player, "maxthrust=1.15 jumpspeed=1.15"); 
	}
	If(playmdl == 4)
	{
		SetInv(player, 60, 80);
		ParseArg(player, "maxthrust=1.3 jumpspeed=1.3");
	}
	If(playmdl == 5)
	{
		SetInv(player, 60, 200);
		ParseArg(player, "maxthrust=0.9 jumpspeed=0.9");
		 
		//Give player Night vision
		ChangeInv(player, 41, 1.0);
      		SetInvAvailable(player, 41, 1);

		//Give him battery charge
		ChangeInv(player, 13, 100.0);
	}

	// Do respawn effects - temporaraly disabled
	//dummy = CreateThingAtPos(teleport_particles, GetThingSector(player), GetThingPos(player), '0 0 0');
	// dummy = PlaySoundThing(teleportsnd, player, 1.0, -1, -1, 0x180);

	//Set our wait
	SetFireWait(player, -1);
	SetMountWait(player, 0);
	SetCurInvWeapon(player, 0);
	//SelectWeapon(player, AutoSelectWeapon(player, 1));
	SelectWeapon(player, 2);

return;

#=======================================================================#

ghostmode:

	player = GetLocalPlayerThing();

	Print("Ghost mode");

	//Send to host that we died.
	SendTrigger(-1, 58, team, 0, 0, 0); 

	//Change players model and movesize etc.
	SendTrigger(-1, 163, 0, 0, 0, 0); 

	//Sendtrigger to dismount weapon (Only if we have one out I spose... let the weapon cogs handle that)
	SendTrigger(player, 62, 0, 0, 0, 0);

	// Set guns. Give them ability to change teams
   	SetInv(player, 1, 0.0);
   	SetInv(player, 2, 0.0);
   	SetInv(player, 3, 0.0);
   	SetInv(player, 4, 0.0);
   	SetInv(player, 5, 0.0);
   	SetInv(player, 6, 0.0);
   	SetInv(player, 7, 0.0);
   	SetInv(player, 8, 0.0);
   	SetInv(player, 9, 1.0);
   	SetInv(player, 10, 0.0);

	//Make the player able to float - flying mode
	ClearPhysicsFlags(player, 0x1);
	SetPhysicsFlags(player, 0x2000);

return;

#=======================================================================#

end


All I did was change that sleep to a timer.

------------------
Team Battle.
Team Battle.
2003-07-18, 10:29 PM #14
Your code is well written with tabs and comments. I love you I love you I love you.

------------------
Bassoon, n. A brazen instrument into which a fool blows out his brains.
Bassoon, n. A brazen instrument into which a fool blows out his brains.
2003-07-19, 4:05 AM #15
My reply was more directed at DeathSythe's example. Just noticed that your messages
don't form an obvious loop where the custom message sends a trigger that will make the
same custom message run.

It's hard to tell what the problem is without being able to test the cog. I'm guessing that
the Sleep() kept too many threads open to receive all of the triggers that the cog sent
to itself.

Replacing the Sleep() will keep the fewest open threads, but I can't see how that's
going to change anything... Unless you have at least one trigger received within the
sleep time. Is there a chance that more than one trigger will be received within three
seconds?

I took your code, modified it slightly, and used a hotkey to send the endround trigger.
No problems. And I built a similar cog that made the same calls and used sleep, still no
problems.

------------------
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
2003-07-19, 10:17 AM #16
okay, lets see if I understand this here....
Point 1 - If you send a trigger, the cog that sends it is paused. And if you send a trigger from that cog back to the sender cog you get an endless loop.

Point 2 - Sleep message pauses the current cog, and if thats under the trigger message, both that cog and the cog that sent the trigger are paused. But if you use a timer, the cog can finish its processes and the sender cog can do so after and then the timer message is triggered after the delay.

Point 3 - There can only be 6 cogs running at one time in JK.

So what is right from all of this and what isn't SM?

------------------
The Sniper Missions. Current project, The Sniper Missions

The Magician Saber System.

The 2 riddle!
Major projects working on:
SATNRT, JK Pistol Mod, Aliens TC, Firearms

Completed
Judgement Day (HLP), My level pack
2003-07-19, 7:45 PM #17
A thread is a lot different from a Cog. A Cog is just a file with a list of instructions.
This list has starting points which are message names and ending points which are
returns.

When a message is sent to a Cog, JK starts a thread for it. This thread will begin at the
message that was sent and keep going until it hits a return statement. When it finds a
return, the thread dies.

I haven't tested with more than one Cog, but I'm assuming that threads are local to the
memory set aside for each Cog. Meaning, using all available threads in one Cog does not
stop another Cog from running all of its threads. The limit for threads seems to be
around six, but that's not certain.

The problem that Hellcat has seems to be too many threads running at once. But DeathSythe's
problem is different in the way that it uses SendTrigger(). Apparently, SendTrigger()
pauses the current thread, and sends the trigger. And if the thread's Cog has a
trigger message, it will start a thread there before going back to the SendTrigger() thread.

The difference with SetTimer() is that this verb does not pause the current thread. It
just sets up the timer, and lets the thread finish.

But as I said above, I'm still not positive on all of this, I'll have to do a lot more testing.

------------------
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
2003-07-20, 6:57 AM #18
okay, I think I get it now. That is why you SM, are the god of cogging.

------------------
The Sniper Missions. Current project, The Sniper Missions

The Magician Saber System.

The 2 riddle!
Major projects working on:
SATNRT, JK Pistol Mod, Aliens TC, Firearms

Completed
Judgement Day (HLP), My level pack
2003-07-20, 8:18 AM #19
Quote:
<font face="Verdana, Arial" size="2">Originally posted by SaberMaster:
This thread will begin at the
message that was sent and keep going until it hits a return statement. When it finds a
return, the thread dies.
</font>


What about a pulse? Will it kill and recreate the thread, or just loop? Seems inefficient to do the former.

------------------
Bassoon, n. A brazen instrument into which a fool blows out his brains.
Bassoon, n. A brazen instrument into which a fool blows out his brains.
2003-07-20, 3:04 PM #20
hehe, thanks Emon.

SM when I upload the next TB beta I will send you a copy to play around with if you like.

------------------
Team Battle.
Team Battle.
2003-07-20, 7:23 PM #21
[http://forums.massassi.net/html/frown.gif] I'm never appricated [http://forums.massassi.net/html/tongue.gif] Not like I did much help, but you need a level done or something or weapons coding/double checking? Sorry but I love AT games, killing terrorists is fun [http://forums.massassi.net/html/biggrin.gif] [http://forums.massassi.net/html/tongue.gif]

------------------
The Sniper Missions. Current project, The Sniper Missions

The Magician Saber System.

The 2 riddle!
Major projects working on:
SATNRT, JK Pistol Mod, Aliens TC, Firearms

Completed
Judgement Day (HLP), My level pack

↑ Up to the top!