Thread: [Plugin] Custom Flashlight

Results 1 to 5 of 5
  1. #1
    Japanese Wannabe NYO~~~! ゞ(´゜ω゜)つ~☆ Nero's Avatar
    Join Date
    Jul 2002
    Location
    Eskilstuna, Sweden.
    Posts
    579

    Standard Crate [Plugin] Custom Flashlight 1.1

    I made a plugin that adds a flashlight that you can customize.

    Feel free to make suggestions!
    Also please try it on a server with other players and get back to me! (SC-devs: please add a way to execute commands on bots <3)


    Console Commands:
    .flashlight <color> - Default: white
    or
    .flashlight [0-255] [0-255] [0-255] - Default: white

    Colors:
    red, green, blue, orange, yellow, lime, turquoise, cyan, purple, pink
    random
    rainbow
    (ADMIN ONLY)

    CVars:
    as_command .fl_radius - Size of the light. (default: 9) (ADMIN ONLY)
    as_command .fl_drain - Rate at which the battery drains. (default: 1.2) (ADMIN ONLY)
    as_command .fl_charge - Rate at which the battery charges. (default: 0.2) (ADMIN ONLY)
    as_command .fl_enabled - Enables/disables the flashlight. (default: 1) (ADMIN ONLY)

    Installation:

    1. Save the following as CustomFlashlight.as in "Steam\steamapps\common\Sven Co-op\svencoop_addon\scripts\plugins" (or download the file)
      Code:
      //Version 1.1
      // CustomFlashlight by Nero
      // ============================
      // 
      // 
      // Based on AMXMODX plugin by ConnorMcLeod in 2008 
      // Thanks to: DeepBlueSea, w00tguy123
      
      /* **************************** CUSTOMIZATION AREA ******************************** */
      
      const string SOUND_FLASHLIGHT_ON = "items/flashlight1.wav";
      const string SOUND_FLASHLIGHT_OFF = "items/flashlight1.wav";
      
      /* ******************************************************************************** */
      
      enum e_colors
      {
      	Red,
      	Green,
      	Blue
      };
      
      CScheduledFunction@ g_pFLThinkFunc = null;
      CCVar@ g_flDrain;
      CCVar@ g_flCharge;
      CCVar@ g_bEnabled;
      CCVar@ g_iRadius;
      
      const uint g_iShowAll = 1;
      const int g_iAttenuation = 5;
      const int g_iDistanceMax = 2000;
      const int iLife	= 2;
      const int MAX_PLAYERS = 32;
      
      array<bool> g_bFlashlight(MAX_PLAYERS+1);
      array<bool> g_bRainbow(MAX_PLAYERS+1);
      array<int> g_iFlashBattery(MAX_PLAYERS+1);
      array<float> g_flFlashLightTime(MAX_PLAYERS+1);
      
      array<array<int>> g_iColor(MAX_PLAYERS+1, array<int>(3));
      
      void PluginInit()
      {
      	g_Module.ScriptInfo.SetAuthor( "Nero" );
      	g_Module.ScriptInfo.SetContactInfo( "Nero @ Svencoop forums" );
        
      	g_Hooks.RegisterHook( Hooks::Player::PlayerKilled, @PlayerKilled );
      	g_Hooks.RegisterHook( Hooks::Player::ClientDisconnect, @ClientDisconnect );
      	g_Hooks.RegisterHook( Hooks::Player::ClientPutInServer, @ClientPutInServer );
      	
      	@g_iRadius = CCVar( "fl_radius", 9, "Size of the light. (default: 9)", ConCommandFlag::AdminOnly );
      	@g_flDrain = CCVar( "fl_drain", 1.2, "Rate at which the battery drains. (default: 1.2)", ConCommandFlag::AdminOnly );
      	@g_flCharge = CCVar( "fl_charge", 0.2, "Rate at which the battery charges. (default: 0.2)", ConCommandFlag::AdminOnly );
      	@g_bEnabled = CCVar( "fl_enabled", 1, "Enables/disables the flashlight. (default: 1)", ConCommandFlag::AdminOnly );
      
      	if( g_pFLThinkFunc !is null )
      		g_Scheduler.RemoveTimer( g_pFLThinkFunc );
      
      	@g_pFLThinkFunc = g_Scheduler.SetInterval( "FL_Think", 0.0f );
      }
      
      CClientCommand flashlight( "flashlight", "Toggles custom flashlight on/off.", @ToggleFL );
      
      void MapInit()
      {
      	g_Game.PrecacheGeneric( "sound/" + SOUND_FLASHLIGHT_ON );
      	g_SoundSystem.PrecacheSound( SOUND_FLASHLIGHT_ON );
      	g_Game.PrecacheGeneric( "sound/" + SOUND_FLASHLIGHT_OFF );
      	g_SoundSystem.PrecacheSound( SOUND_FLASHLIGHT_OFF );
      }
      
      HookReturnCode ClientPutInServer( CBasePlayer@ pPlayer )
      {
      	reset( pPlayer );
      	int iIndex = pPlayer.entindex();
      	
      	g_iColor[iIndex][Red] = 255;
      	g_iColor[iIndex][Green] = 255;
      	g_iColor[iIndex][Blue] = 255;
      	g_bRainbow[iIndex] = false;
      	
      	return HOOK_CONTINUE;
      }
      
      HookReturnCode PlayerKilled( CBasePlayer@ pPlayer, CBaseEntity@ pAttacker, int iGib )
      {
      	reset( pPlayer );
      	
      	return HOOK_CONTINUE;
      }
      
      HookReturnCode ClientDisconnect( CBasePlayer@ pPlayer )
      {
      	FlashlightTurnOff( pPlayer );
       
      	return HOOK_CONTINUE;
      }
      
      void reset( CBasePlayer@ pPlayer )
      {
      	int iIndex = pPlayer.entindex();
      	
      	g_iFlashBattery[ iIndex ] = 100;
      	g_bFlashlight[ iIndex ] = false;
      	g_bRainbow[ iIndex ] = false;
      	g_flFlashLightTime[ iIndex ] = 0.0;
      }  
      
      void ToggleFL( const CCommand@ args )
      {
      	CBasePlayer@ pPlayer = g_ConCommandSystem.GetCurrentPlayer();
      	int iIndex = pPlayer.entindex();
      
      	if( g_bEnabled.GetBool() )
      	{
      		if( pPlayer.IsAlive() )
      		{
      			if ( args.ArgC() == 1 )
      			{
      				g_iColor[iIndex][Red] = 128;
      				g_iColor[iIndex][Green] = 128;
      				g_iColor[iIndex][Blue] = 128;
      			}
      			else if ( args.ArgC() == 2 )
      			{
      				if( args.Arg( 1 ) == "rainbow" )
      					if(g_PlayerFuncs.AdminLevel( pPlayer ) <= ADMIN_YES)
      					{
      						g_PlayerFuncs.ClientPrint( pPlayer, HUD_PRINTTALK, "[Flashlight] That color is only for admins.\n" );
      						return;
      					}
      					else
      						g_bRainbow[ iIndex ] = true;
      				else if( args.Arg( 1 ) == "random" )
      				{
      					g_iColor[iIndex][Red] = Math.RandomLong( 0, 255 );
      					g_iColor[iIndex][Green] = Math.RandomLong( 0, 255 );
      					g_iColor[iIndex][Blue] = Math.RandomLong( 0, 255 );
      				}
      				else if( args.Arg( 1 ) == "red" )
      				{
      					g_iColor[iIndex][Red] = 255;
      					g_iColor[iIndex][Green] = 0;
      					g_iColor[iIndex][Blue] = 0;
      				}
      				else if( args.Arg( 1 ) == "green" )
      				{
      					g_iColor[iIndex][Red] = 0;
      					g_iColor[iIndex][Green] = 255;
      					g_iColor[iIndex][Blue] = 0;
      				}
      				else if( args.Arg( 1 ) == "blue" )
      				{
      					g_iColor[iIndex][Red] = 0;
      					g_iColor[iIndex][Green] = 0;
      					g_iColor[iIndex][Blue] = 255;
      				}
      				else if( args.Arg( 1 ) == "orange" )
      				{
      					g_iColor[iIndex][Red] = 255;
      					g_iColor[iIndex][Green] = 128;
      					g_iColor[iIndex][Blue] = 0;
      				}
      				else if( args.Arg( 1 ) == "yellow" )
      				{
      					g_iColor[iIndex][Red] = 255;
      					g_iColor[iIndex][Green] = 255;
      					g_iColor[iIndex][Blue] = 0;
      				}
      				else if( args.Arg( 1 ) == "lime" )
      				{
      					g_iColor[iIndex][Red] = 128;
      					g_iColor[iIndex][Green] = 255;
      					g_iColor[iIndex][Blue] = 0;
      				}
      				else if( args.Arg( 1 ) == "turquoise" )
      				{
      					g_iColor[iIndex][Red] = 0;
      					g_iColor[iIndex][Green] = 255;
      					g_iColor[iIndex][Blue] = 200;
      				}
      				else if( args.Arg( 1 ) == "cyan" )
      				{
      					g_iColor[iIndex][Red] = 0;
      					g_iColor[iIndex][Green] = 128;
      					g_iColor[iIndex][Blue] = 255;
      				}
      				else if( args.Arg( 1 ) == "purple" )
      				{
      					g_iColor[iIndex][Red] = 128;
      					g_iColor[iIndex][Green] = 0;
      					g_iColor[iIndex][Blue] = 255;
      				}
      				else if( args.Arg( 1 ) == "pink" )
      				{
      					g_iColor[iIndex][Red] = 255;
      					g_iColor[iIndex][Green] = 0;
      					g_iColor[iIndex][Blue] = 255;
      				}
      				else
      				{
      					g_PlayerFuncs.ClientPrint( pPlayer, HUD_PRINTTALK, "[Flashlight] No such color.\n" );
      					return;
      				}
      			}
      			else if ( args.ArgC() == 4 )
      			{
      				if( atoi( args.Arg( 1 ) ) >= 0 && atoi( args.Arg( 1 ) ) <= 255 && atoi( args.Arg( 2 ) ) >= 0 && atoi( args.Arg( 2 ) ) <= 255 && atoi( args.Arg( 3 ) ) >= 0 && atoi( args.Arg( 3 ) ) <= 255 )
      				{
      					g_iColor[iIndex][Red] = atoi( args.Arg( 1 ) );
      					g_iColor[iIndex][Green] = atoi( args.Arg( 2 ) );
      					g_iColor[iIndex][Blue] = atoi( args.Arg( 3 ) );
      				}
      				else
      				{
      					g_PlayerFuncs.ClientPrint( pPlayer, HUD_PRINTTALK, "[Flashlight] Usage: .flashlight <color> or <0-255> <0-255> <0-255>\n" );
      					return;
      				}
      			}
      			else
      			{
      				g_PlayerFuncs.ClientPrint( pPlayer, HUD_PRINTTALK, "[Flashlight] Usage: .flashlight <color> or <0-255> <0-255> <0-255>\n" );
      				return;
      			}
      			
      			if ( g_bFlashlight[ iIndex ] )
      			{
      				FlashlightTurnOff( pPlayer );
      			}
      			else if( g_iFlashBattery[ iIndex ] >= 1 )
      			{
      				FlashlightTurnOn( pPlayer );
      			}
      		}
      	}
      }
      
      void FL_Think()
      {
      	float flTime = g_Engine.time;
      	for ( int i = 1; i <= g_Engine.maxClients; ++i )
      	{
      		CBasePlayer@ pPlayer = g_PlayerFuncs.FindPlayerByIndex(i);
      		if ( pPlayer is null )
      			continue;
      
      		int iIndex = pPlayer.entindex();
      		
      		if( ( g_flDrain.GetFloat() > 0.0 ) && ( g_flFlashLightTime[ iIndex ] > 0.0 ) && ( g_flFlashLightTime[ iIndex ] <= flTime ) )
      		{
      			if( g_bFlashlight[ iIndex ] )
      			{
      				if( g_iFlashBattery[ iIndex ] >= 1 )
      				{
      					g_flFlashLightTime[ iIndex ] = g_flDrain.GetFloat() + flTime;
      					--g_iFlashBattery[ iIndex ];
      					
      					if( g_iFlashBattery[ iIndex ] <= 0 )
      					{
      						FlashlightTurnOff( pPlayer );
      					}
      				}
      			}
      			else
      			{
      				if( g_iFlashBattery[ iIndex ] < 100 )
      				{
      					g_flFlashLightTime[ iIndex ] = g_flCharge.GetFloat() + flTime;
      					++g_iFlashBattery[ iIndex ];
      				}
      				else
      					g_flFlashLightTime[ iIndex ] = 0.0;
      			}
      			
      			NetworkMessage flbatt( MSG_ONE_UNRELIABLE, NetworkMessages::FlashBat, pPlayer.edict() );
      				flbatt.WriteByte( g_iFlashBattery[ iIndex ] );
      			flbatt.End();
      
      		}
      		if( g_bFlashlight[ iIndex ] )
      		{
      			MakeFlashlight( pPlayer );
      		}
      	}
      }
      
      void MakeFlashlight( CBasePlayer@ pPlayer )
      {
      	Vector iOrigin = pPlayer.GetGunPosition();
      	TraceResult iAim;
      	g_Utility.TraceLine( iOrigin, iOrigin + g_Engine.v_forward * g_iDistanceMax, dont_ignore_monsters, pPlayer.edict(), iAim );
      	float iDist = ( iOrigin - iAim.vecEndPos ).Length();
      	int iIndex = pPlayer.entindex();
      	
      	if( iDist > g_iDistanceMax )
      		return;
      
      	float iDecay, iAttn;
      	iDecay = iDist * 255 / g_iDistanceMax;
      	iAttn = 256 + iDecay * g_iAttenuation;
      
      	if( g_bRainbow[iIndex] )
      	{
      		g_iColor[iIndex][Red] = Math.RandomLong( 0, 255 );
      		g_iColor[iIndex][Green] = Math.RandomLong( 0, 255 );
      		g_iColor[iIndex][Blue] = Math.RandomLong( 0, 255 );
      	}
      	
      	if( g_iShowAll == 1 )
      	{
      		NetworkMessage flon( MSG_BROADCAST, NetworkMessages::SVC_TEMPENTITY );
      			flon.WriteByte( TE_DLIGHT );
      			flon.WriteCoord( iAim.vecEndPos.x );
      			flon.WriteCoord( iAim.vecEndPos.y );
      			flon.WriteCoord( iAim.vecEndPos.z );
      			flon.WriteByte( g_iRadius.GetInt() );
      			flon.WriteByte( int((g_iColor[iIndex][Red]<<8) / iAttn) );
      			flon.WriteByte( int((g_iColor[iIndex][Green]<<8) / iAttn) );
      			flon.WriteByte( int((g_iColor[iIndex][Blue]<<8) / iAttn) );
      			flon.WriteByte( iLife );
      			flon.WriteByte( int(iDecay) );
      		flon.End();
      	}
      	else
      	{
      		NetworkMessage flon( MSG_ONE_UNRELIABLE, NetworkMessages::SVC_TEMPENTITY, pPlayer.edict() );
      			flon.WriteByte( TE_DLIGHT );
      			flon.WriteCoord( iAim.vecEndPos.x );
      			flon.WriteCoord( iAim.vecEndPos.y );
      			flon.WriteCoord( iAim.vecEndPos.z );
      			flon.WriteByte( g_iRadius.GetInt() );
      			flon.WriteByte( int((g_iColor[iIndex][Red]<<8) / iAttn) );
      			flon.WriteByte( int((g_iColor[iIndex][Green]<<8) / iAttn) );
      			flon.WriteByte( int((g_iColor[iIndex][Blue]<<8) / iAttn) );
      			flon.WriteByte( iLife );
      			flon.WriteByte( int(iDecay) );
      		flon.End();
      	}
      }
      
      void FlashlightTurnOff( CBasePlayer@ pPlayer )
      {
      	int iIndex = pPlayer.entindex();
      	
      	g_SoundSystem.EmitSoundDyn( pPlayer.edict(), CHAN_WEAPON, SOUND_FLASHLIGHT_OFF, VOL_NORM, ATTN_NORM, 0, PITCH_NORM );
      
      	g_bFlashlight[ iIndex ] = false;
      	g_bRainbow[ iIndex ] = false;
      
      	FlashlightHudDraw( pPlayer, 0 );
      
      	g_flFlashLightTime[ iIndex ] = g_flCharge.GetFloat() + g_Engine.time;
      }
      
      void FlashlightTurnOn( CBasePlayer@ pPlayer )
      {
      	int iIndex = pPlayer.entindex();
      
      	g_SoundSystem.EmitSoundDyn( pPlayer.edict(), CHAN_WEAPON, SOUND_FLASHLIGHT_ON, VOL_NORM, ATTN_NORM, 0, PITCH_NORM );
      
      	g_bFlashlight[ iIndex ] = true;
      
      	FlashlightHudDraw( pPlayer, 1 );
      
      	g_flFlashLightTime[ iIndex ] = g_flDrain.GetFloat() + g_Engine.time;
      }
      
      void FlashlightHudDraw( CBasePlayer@ pPlayer, uint iFlag )
      {
      	int iIndex = pPlayer.entindex();
      	
      	NetworkMessage fl( MSG_ONE_UNRELIABLE, NetworkMessages::Flashlight, pPlayer.edict() );
      		fl.WriteByte( iFlag );
      		fl.WriteByte( g_iFlashBattery[ iIndex ] );
      	fl.End();
      }
    2. Add this to the bottom of "Steam\steamapps\common\Sven Co-op\svencoop\default_plugins.txt"
      Code:
          "plugin"
          {
              "name" "CustomFlashlight"
              "script" "CustomFlashlight"
          }
    3. ???
    4. Profit.

    ToDo:
    • Make the rainbow fade slower between colors.
    • Lower brightness?
    • Add more colors


    Changelog:
    • 1.1 - Lowered default color brightness
    • 1.1 - Added CVars
    • 1.1 - Added .flashlight <r> <g> <b>
    • 1.0 - Release


    Attached Files Attached Files
    Last edited by Nero; 08-04-2016 at 12:54 AM. Reason: fix'd custom precache thingie
    Nero of TSP and Wotnet
    Ingame names: Nero, Horny-Girl-13
    IRC nick: Nero (probably)

  2. #2
    Game tester  
    Tester
    Join Date
    Aug 2009
    Location
    Sao Paulo, Brazil
    Posts
    212

    Re: [Plugin] Custom Flashlight

    Code:
    void MapInit()
    {
    	g_Game.PrecacheGeneric( SOUND_FLASHLIGHT_ON );
    	g_SoundSystem.PrecacheSound( SOUND_FLASHLIGHT_ON );
    	g_Game.PrecacheGeneric( SOUND_FLASHLIGHT_OFF );
    	g_SoundSystem.PrecacheSound( SOUND_FLASHLIGHT_OFF );
    }
    I'm not an coder, but why do you precache same file using generic precache too? This is causing file not found errors like "Warning: Unable to open items/flashlight1.wav for transfer" because PrecacheGeneric() does not follow sound path itself(?)

    Correct me if I'm wrong.

  3. #3
    Banned Solokiller's Avatar
    Join Date
    Sep 2004
    Location
    Belgium
    Posts
    3,314

    Re: [Plugin] Custom Flashlight

    PrecacheSound will not precache the file itself for download. This is because the sound system isn't implemented in the engine, so its precache list doesn't affect downloads.

  4. #4
    Japanese Wannabe NYO~~~! ゞ(´゜ω゜)つ~☆ Nero's Avatar
    Join Date
    Jul 2002
    Location
    Eskilstuna, Sweden.
    Posts
    579

    Re: [Plugin] Custom Flashlight

    Awww crap, I didn't think of that. Thanks! <3
    Does it work with more than 1 player though? :o


    edit: fix'd :3
    Last edited by Nero; 08-04-2016 at 12:55 AM.
    Nero of TSP and Wotnet
    Ingame names: Nero, Horny-Girl-13
    IRC nick: Nero (probably)

  5. #5
    Japanese Wannabe NYO~~~! ゞ(´゜ω゜)つ~☆ Nero's Avatar
    Join Date
    Jul 2002
    Location
    Eskilstuna, Sweden.
    Posts
    579

    Re: [Plugin] Custom Flashlight

    Quote Originally Posted by R4to0 View Post
    I'm not an coder, but why do you precache same file using generic precache too?

    This is what nico said to me in another post:

    "hud_nightvision_off.wav is a custom sound, you need to also PrecacheGeneric() it before PrecacheSound().

    PrecacheGeneric -> stuff gets downloaded, not needed if the sound is in the base content
    PrecacheSound -> sound is precached for actually playing it "

    :3
    Nero of TSP and Wotnet
    Ingame names: Nero, Horny-Girl-13
    IRC nick: Nero (probably)

Posting Permissions

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