Results 1 to 8 of 8

Thread: Spawnable Triggers

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #6
    Brigadier General
    Join Date
    Oct 2012
    Posts
    994
    Thanks
    20
    Thanked 588 Times in 388 Posts
    Quote Originally Posted by kung foo man View Post
    Well, normal spawnable triggers are spheres only and this is box + debug lines, which are kinda helpful.
    But it's the efficiency of the code that is questionable. It can all be done so much simpler and just as effectively, without putting such a strain on the server. This is my universal trigger function for COD1, which doesn't natively support triggers which can be delimited by radius (there is no trigger_radius in COD1 - only trigger_multiple can be spawned dynamically):

    Code:
    spawnTrigger( origin, radius )
    {
    	ent = spawn( "script_origin", origin );
    	ent.origin = origin;
    	ent.touchingPlayer = [];
    	ent.touchingRadius = radius;
    	ent thread flag_touching();
    	
    	return( ent );
    }
    
    flag_touching()
    {
    	level endon( "intermission" );
    	
    	/#
    	showBoundedArea( self, (1,0,0) );
    	#/
    
    	for( ;; )
    	{
    		players = getEntArray( "player", "classname" );
    			
    		for( i=0; i < players.size; i++ )
    		{
    			player = players[i];
    			
    			if( isPlayer( player ) && isAlive( player ) && player.sessionstate == "playing" )
    			{	
    				if( distance( self.origin, player.origin ) < self.touchingRadius )
    				{
    					self notify( "trigger", player );
    				}
    			}
    		}
    		
    		wait( 0.05 );
    	}
    }
    
    
    showBoundedArea( trigger, color )
    {
    	player_height = 80.0;
    	center = trigger.origin;
    	forward = anglestoforward( trigger.angles );
    	right = anglestoright( trigger.angles );
    
    	forward = maps\mp\_utility::vectorScale( forward, trigger.touchingRadius );
    	right = maps\mp\_utility::vectorScale( right, trigger.touchingRadius );
    
    	a = center + forward - right;
    	b = center + forward + right;
    	c = center - forward + right;
    	d = center - forward - right;
    	
    	thread lineUntilNotified( a, b, color, 0 );
    	thread lineUntilNotified( b, c, color, 0 );
    	thread lineUntilNotified( c, d, color, 0 );
    	thread lineUntilNotified( d, a, color, 0 );
    
    	thread lineUntilNotified( a, a + (0, 0, player_height), color, 0 );
    	thread lineUntilNotified( b, b + (0, 0, player_height), color, 0 );
    	thread lineUntilNotified( c, c + (0, 0, player_height), color, 0 );
    	thread lineUntilNotified( d, d + (0, 0, player_height), color, 0 );
    
    	a = a + ( 0, 0, player_height );
    	b = b + ( 0, 0, player_height );
    	c = c + ( 0, 0, player_height );
    	d = d + ( 0, 0, player_height );
    	
    	thread lineUntilNotified( a, b, color, 0 );
    	thread lineUntilNotified( b, c, color, 0 );
    	thread lineUntilNotified( c, d, color, 0 );
    	thread lineUntilNotified( d, a, color, 0 );
    	
    }
    
    lineUntilNotified( start, end, color, depthTest )
    {	
    	for( ;; )
    	{
    		line( start, end, color, depthTest );
    		wait( 0.05 );
    	}
    }
    And the developer mode produces this marked bounded area:



    In the gametype files, you code it as if it were a trigger_radius. This is my trigger think for CTF for COD1:

    Code:
    flag_think()
    {
    	level endon( "intermission" );
    	
    	objective_add( self.objective, "current", self.origin, self.compassflag );
    
    	for( ;; )
    	{
    		self waittill( "trigger", player );
    			
    		if( isPlayer( player ) && isAlive( player ) && player.sessionstate == "playing" )
    		{	
    			// PICKUP THE FLAG !!
    			if( player.pers["team"] != self.team )
    			{
    				if( self.atbase )
    				{
    					if( player.pers["team"] == "allies" )
    						player AnnouncetoAll( &"CTF_STOLE_AXIS", player.name );
    					else
    						player AnnouncetoAll( &"CTF_STOLE_ALLIES", player.name );
    					
    					thread logEvent( "ctf_pickedup_flag", player );
    				}
    				else
    				{
    					if( player.pers["team"] == "allies" )
    						player AnnouncetoAll( &"CTF_TAKEN_BACK_AXIS", player.name );
    					else
    						player AnnouncetoAll( &"CTF_TAKEN_BACK_ALLIES", player.name );
    						
    					thread logEvent( "ctf_pickedup_dropped_flag", player );
    				}
    				
    				player pickupFlag( self );
    
    				friendlyAlias = "ctf_touchenemy";
    				enemyAlias = "ctf_enemy_touchenemy";
    				
    				thread [[level.onPlaySoundOnPlayers]]( friendlyAlias, self.team );
    				thread [[level.onPlaySoundOnPlayers]]( enemyAlias, [[level.getOtherTeam]]( self.team ) );
    							
    				thread [[level.onPlaySoundOnPlayers]]( game["flagTaken"][ player.pers["team"] ], player.pers["team"] );
    
    			}
    			else 
    			{
    				// CAPTURED THE FLAG !!
    				if( self.atbase )
    				{
    					if( isdefined( player.flag ) )
    					{
    						player.flag returnFlag( undefined );
    						player detachFlag( player.flag );
    						player.flag = undefined;
    						player.statusicon = "";
    
    						player.score += 10;
    						teamscore = getTeamScore( player.pers["team"] );
    						teamscore += 1;
    						setTeamScore( player.pers["team"], teamscore );
    						level notify( "update_allhud_score");
    	
    						if( player.pers["team"] == "allies" )
    							self AnnouncetoAll( &"CTF_CAPTURED_AXIS", player.name );
    						else
    							self AnnouncetoAll( &"CTF_CAPTURED_ALLIES", player.name );	
    
    						friendlyAlias = "ctf_touchcapture";
    						enemyAlias = "ctf_enemy_touchcapture";
    
    						thread [[level.onPlaySoundOnPlayers]]( game["flagCapped"][ [[level.getOtherTeam]]( player.pers["team"] ) ] );
    
    						thread [[level.onPlaySoundOnPlayers]]( friendlyAlias, player.pers["team"] );
    						thread [[level.onPlaySoundOnPlayers]]( enemyAlias, [[level.getOtherTeam]]( player.pers["team"] ) );
    						
    						thread logEvent( "ctf_captured_flag", player );
    
    						maps\mp\gametypes\_globallogic::checkScoreLimit();
    					}
    				}
    				else // RETURNED FLAG TO BASE !!
    				{							
    					self returnFlag( true );
    
    					if( self.team == "allies" )
    						self AnnouncetoAll( &"CTF_RETURNED_ALLIES", player.name );
    					else
    						self AnnouncetoAll( &"CTF_RETURNED_AXIS", player.name );
    						
    					thread [[level.onPlaySoundOnPlayers]]( "ctf_touchown", player.pers["team"] );
    						
    					thread logEvent( "ctf_returned_own_flag", player );
    					
    					player.score += 2;
    					level notify( "update_allhud_score" );
    				}
    			}
    		}
    		
    		wait( 0.05 );
    	}
    }
    Ockham's Razor: All things being equal, the SIMPLEST solution is the right one. And my method - the method used by modders before trigger_radius was introduced in COD2 - is to use a distance test of a script_origin against all players. Such a method is less server CPU heavy than SniperFire's method.
    Last edited by Tally; 5th December 2014 at 07:27.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •