an advice for triggers

Have a question about modding, modelling or skinning? Have a tutorial to post? Post here!

Moderator: Core Staff

megazor
CJ Worshipper
CJ Worshipper
Posts: 414
Joined: July 22nd, 2009, 3:02 am
Location: Russia, Vladivostok

an advice for triggers

Post by megazor » June 7th, 2010, 9:45 am

here is a simple code majority of people use:

Code: Select all

trig waittill("trigger", player);
do stuff with the player...
it catches only one player, regardless of amount of players touching the trigger.
if several players are touching the trigger, the game chooses a random one.
sometimes that doesn't matter, but in some cases it does.
if 20 players are touching the trigger, the probability of being caught by the script is 1/20 for each player.
as it is random, some player may be waiting rather long before getting caught.
For some cases getting caught immediately on touch is important.

For that use the code below (it assumes the trig and the players are defined as entities):

Code: Select all

for (i = 0; i < players.size; i++)
     if (players[i] isTouching(trig))
          do stuff with the player
don't forget to check a player's sessionstate if it is important (it usually is).

User avatar
Drofder2004
Core Staff
Core Staff
Posts: 13313
Joined: April 13th, 2005, 8:22 pm
Location: UK, London

Re: an advice for triggers

Post by Drofder2004 » June 7th, 2010, 8:07 pm

Code: Select all

fucntion_a()
{
   while(1)
   {
      entity waittill ("trigger", user);
      user function_b();
   }
}

function_b()
{
   self iprintln("This thread is running on " + self.name);
}
There are no wait functions in this script, it will hit ALL players who touch the trigger, but it will also cause stress on the server because of the amount of threads being created.

Fixed by doing:

Code: Select all

fucntion_a()
{
   while(1)
   {
      entity waittill ("trigger", user);
      if(!isDefined(user.checkuser)
         user function_b();
   }
}

function_b()
{
   self.checkuser = 1;
   self iprintln("This thread is running on " + self.name);
   wait 1;
   self.checkuser = undefined;
}
You function will loop 20 times every 0.05 seconds = 400 threads a second.
Mine will only activate when touched = 20 threads per second.
Image
Virgin Media 20Mb Broadband:
"Perfect for families going online at the same time, downloading movies, online gaming and more."
Borked internet since: 22-07-2010

megazor
CJ Worshipper
CJ Worshipper
Posts: 414
Joined: July 22nd, 2009, 3:02 am
Location: Russia, Vladivostok

Re: an advice for triggers

Post by megazor » June 7th, 2010, 10:53 pm

no, in your second code it is only one thread per a second, coz you have user function(), not user thread function(); and that function has a wait 1.

Pedsdude
Site Admin
Site Admin
Posts: 15909
Joined: October 15th, 2004, 7:18 pm
Location: UK

Re: an advice for triggers

Post by Pedsdude » June 7th, 2010, 11:13 pm

Image
Image
Image

User avatar
Drofder2004
Core Staff
Core Staff
Posts: 13313
Joined: April 13th, 2005, 8:22 pm
Location: UK, London

Re: an advice for triggers

Post by Drofder2004 » June 8th, 2010, 12:51 am

megazor wrote:no, in your second code it is only one thread per a second, coz you have user function(), not user thread function(); and that function has a wait 1.
We are using a "wait till" function, which has a wait time of 0. The other wait time is cosmetic and can be removed.

Image
Image
Virgin Media 20Mb Broadband:
"Perfect for families going online at the same time, downloading movies, online gaming and more."
Borked internet since: 22-07-2010

megazor
CJ Worshipper
CJ Worshipper
Posts: 414
Joined: July 22nd, 2009, 3:02 am
Location: Russia, Vladivostok

Re: an advice for triggers

Post by megazor » June 8th, 2010, 3:23 am

Code: Select all

We are using a "wait till" function, which has a wait time of 0
actually (at least in cod1) waittill function catches the player only on a server's frame.

you still don't understand. waittill() gets a RANDOM entity!!! RANDOM! that means it may catch THE SAME player lots of times! and it doesn't guarantee that the necessary player will be caught fast enough.

megazor
CJ Worshipper
CJ Worshipper
Posts: 414
Joined: July 22nd, 2009, 3:02 am
Location: Russia, Vladivostok

Re: an advice for triggers

Post by megazor » June 8th, 2010, 4:32 am

I've just tested your code, and it wasn't working finely - just as I expected. Sometimes there were long pauses (over one second) between the messages - that means failure. rofl. maybe maybe maybe in cod4 waittill() chooses not a random player, it goes through all the players touching the trigger, but in cod1 it doesn't.

I figuried out the best way:

Code: Select all

trig waittill ("trigger");
for (i= 0; i < players.size; i++)
     if (players[i] isTouching(trig))
          do stuff
so a lot of threads are going only while anyone is touching the trigger.

User avatar
Nightmare
Core Staff
Core Staff
Posts: 2688
Joined: January 12th, 2006, 10:09 pm
Contact:

Re: an advice for triggers

Post by Nightmare » June 8th, 2010, 7:22 pm

megazor wrote:I've just tested your code, and it wasn't working finely - just as I expected. Sometimes there were long pauses (over one second) between the messages - that means failure. rofl. maybe maybe maybe in cod4 waittill() chooses not a random player, it goes through all the players touching the trigger, but in cod1 it doesn't.

I figuried out the best way:

Code: Select all

trig waittill ("trigger");
for (i= 0; i < players.size; i++)
     if (players[i] isTouching(trig))
          do stuff
so a lot of threads are going only while anyone is touching the trigger.
You're really arguing against the wrong person, his code is fine, except for one thing (sorry drof).
If you're really afraid of the code triggering "random" people without creating a crazy amount of threads, then try this:

Code: Select all

fucntion_a()
{
   while(1)
   {
      entity waittill ("trigger", user);
      if(!isDefined(user.checkuser)
         user thread function_b();
   }
}

function_b()
{
   self.checkuser = 1;
   self iprintln("This thread is running on " + self.name);
   wait 1;
   self.checkuser = undefined;
}
Before you go saying that this code is exactly the same as his, there is a small modification I made:

Code: Select all

user thread function_b();
Using the "thread" keyword will tell the script to keep on running through and not wait for the threaded function to complete.

Try it now, there shouldn't be any problems.

Also: give some respect to those who are willing to help.
Coding is Poetry. Mapping is Art.
"Cause im the sexiest mapper ever...except for nm, that sexy man" - Soviet

-=[CoDJumper.com Movies]=-
[Ambush] || [Backlot] || [Bloc] || [Bog] || [Broadcast] || [Chinatown] || [Countdown]
[Crash] || [Creek] || [Crossfire] || [District] || [Downpour] || [Killhouse] || [Overgrown]
[Pipeline] || [Shipment & Wetwork] || [Showdown] || [Strike] || [Vacant]

User avatar
Drofder2004
Core Staff
Core Staff
Posts: 13313
Joined: April 13th, 2005, 8:22 pm
Location: UK, London

Re: an advice for triggers

Post by Drofder2004 » June 8th, 2010, 7:50 pm

Nightmare wrote:

Code: Select all

user thread function_b();
Oops, well spotted without that, the script does feck all :P
Image
Virgin Media 20Mb Broadband:
"Perfect for families going online at the same time, downloading movies, online gaming and more."
Borked internet since: 22-07-2010

User avatar
Drofder2004
Core Staff
Core Staff
Posts: 13313
Joined: April 13th, 2005, 8:22 pm
Location: UK, London

Re: an advice for triggers

Post by Drofder2004 » June 8th, 2010, 8:18 pm

megazor wrote:

Code: Select all

We are using a "wait till" function, which has a wait time of 0
actually (at least in cod1) waittill function catches the player only on a server's frame.

you still don't understand. waittill() gets a RANDOM entity!!! RANDOM! that means it may catch THE SAME player lots of times! and it doesn't guarantee that the necessary player will be caught fast enough.
I can assure you there is nothing "random" about this code. The "if()" checks for an existing thread and then loops and tries again. Because there is ZERO wait time, all entities that set off the trigger are detected.

Trust us, we have been using this code since CoD1.
Image
Virgin Media 20Mb Broadband:
"Perfect for families going online at the same time, downloading movies, online gaming and more."
Borked internet since: 22-07-2010

megazor
CJ Worshipper
CJ Worshipper
Posts: 414
Joined: July 22nd, 2009, 3:02 am
Location: Russia, Vladivostok

Re: an advice for triggers

Post by megazor » June 8th, 2010, 10:55 pm

guys, i wont trust you, because the game tells the truth. i tested the code - it WAS NOT working, you think i copied it in wrong way? hardly ever, lol.

u both still do not understand me. it chooses RANDOM RANDOM RANDOM user, if several players TOUCHING the entity, it get random player, and now pay your attention: it FIRSTlY catches a player, and only AFTER that it checks if the player fits.
read that again: it may choose the same player many times. it is not a loop going though all players from first to the last.
I was trsting your code by two players, and i also made a loop that runs two waittill on one server frame, and sometimes i was not getting the two different messages: "mega running thread" and "lolzor running thread" - sometimes it was showing me:
"mega running thread" and "mega running thread", and the same to lolzor - so it sometimes caught the same player.

i won't say, "sorrry for caps", coz that turned out to be the only way to express what i talked about -.-
Last edited by megazor on June 9th, 2010, 3:34 am, edited 2 times in total.

User avatar
Nightmare
Core Staff
Core Staff
Posts: 2688
Joined: January 12th, 2006, 10:09 pm
Contact:

Re: an advice for triggers

Post by Nightmare » June 9th, 2010, 1:33 am

You know what Drof? This man is absolutely right in every single way and perspective you and I can think of.
Carry on with your code. Tell us how it goes when you do this for multiple triggers.
Coding is Poetry. Mapping is Art.
"Cause im the sexiest mapper ever...except for nm, that sexy man" - Soviet

-=[CoDJumper.com Movies]=-
[Ambush] || [Backlot] || [Bloc] || [Bog] || [Broadcast] || [Chinatown] || [Countdown]
[Crash] || [Creek] || [Crossfire] || [District] || [Downpour] || [Killhouse] || [Overgrown]
[Pipeline] || [Shipment & Wetwork] || [Showdown] || [Strike] || [Vacant]

megazor
CJ Worshipper
CJ Worshipper
Posts: 414
Joined: July 22nd, 2009, 3:02 am
Location: Russia, Vladivostok

Re: an advice for triggers

Post by megazor » June 9th, 2010, 3:32 am

drofder is mistaken here. an example:

there are some water and a trigger covering it; if the player touches the trigger, he drowns moving downstaris. so while he is drowning, he touches the trigger, but as the player is already drowning, it does nothing to him because of his variable (like player.drowning) But imagine 19 players are drowning, and only one isn't; and while they are still drowning, he touches the trigger. what is the probability the trigger will catch him? 1/20. maybe it will catch him fast, maybe he will be waiting for a minute. maybe - ages. and the only cause is random choice. if some player doesn't fit to the trigger (he has the variable), then the trigger will choose a random player again, and it may catch the same player. the only thing here i hate is the necessary player has to wait some time before getting caught by the trigger.

megazor
CJ Worshipper
CJ Worshipper
Posts: 414
Joined: July 22nd, 2009, 3:02 am
Location: Russia, Vladivostok

Re: an advice for triggers

Post by megazor » June 9th, 2010, 7:47 am

unfortunately you still and still do not understand. yes, it does detect all entities, but from the list it chooses a random one.
as fast as i see my words dont help, maybe the code below will?

Code: Select all

function()
{
	trig = getEnt("jump240_trig", "targetname");
   	while(1)
   	{
		players = getEntArray("player", "classname");
		for (i = 0; i < players.size; i++)
		{
      			trig waittill ("trigger", user);
			iprintln("caught "+user.name);	
		}
	wait 1;
   	}
}
as you can see, function waittill() runs several times on one server frame (wait 0). according to you posts, is it supposed to print names of different players. i tested this function using two players. sometimes i was getting two identical names (both players had different names, obviously), and that means it caught the same player two times. just test this function, and you will be convinced of that.

without wait 1 the while(1) loop goes very fast: about 100 times per a second, although the minimal time is 0.05 (server fps were 20). it was really like 100-120, bcoz it reached 1000 within 10 seconds (i used a counter to check it).

i have also tested nightmare's code with 4 players, all of them were touching the trigger, and yes - each player was getting caught fast. but that happened, because the loop was going very fast - as i said, about 100 times per a second which makes the probability of getting caught pretty high (the array made of 4 players is too little). who knows what would happen if there were 20 players. can't test it, as my pc is too bad for running 20 copies of the game.

anyway you couldn't avoid having too many loops (100 per a second), so your code doesn't win.

megazor
CJ Worshipper
CJ Worshipper
Posts: 414
Joined: July 22nd, 2009, 3:02 am
Location: Russia, Vladivostok

Re: an advice for triggers

Post by megazor » June 9th, 2010, 7:54 am

well, actually if there are 1 000 000 players and the loop goes through them 1 000 000 times, the probability of getting the one necessary player is the same as if there were 10 players and 10 loops. i think the probability is 1/2. but the main issue is overlooping, so that method is shitty. just as mine, actually, rofl. who can think up a proper way?

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest