[CS:GO] Color flashlight with adjustable radius

A place for requesting new Source.Python plugins to be made for your server.

Please request only one plugin per thread.
jocik
Junior Member
Posts: 7
Joined: Sat Jan 23, 2021 12:07 am
Location: Poland

[CS:GO] Color flashlight with adjustable radius

Postby jocik » Sat Jan 23, 2021 12:11 am

Hello guys!

Can anyone help me by providing such plugin? Is it possible to make something like this for CS:GO?

The flashlight should has adjustable color (set from server point of view), like red, green, blue... And also adjustable radius.

Thanks in advance,
Jocik.
User avatar
VinciT
Senior Member
Posts: 331
Joined: Thu Dec 18, 2014 2:41 am

Re: [CS:GO] Color flashlight with adjustable radius

Postby VinciT » Sat Jan 23, 2021 11:29 pm

Hi jocik, give this a try:

Syntax: Select all

# ../flashlight/flashlight.py

# Python
from colorsys import hsv_to_rgb

# Source.Python
from colors import Color
from commands import CommandReturn
from commands.client import ClientCommand
from entities.entity import Entity
from listeners import OnNetworkedEntityDeleted
from mathlib import NULL_VECTOR, NULL_QANGLE
from players.entity import Player


# Color of the flashlight.
FLASHLIGHT_COLOR = Color(255, 255, 255)
# Radius of the flashlight.
FLASHLIGHT_RADIUS = 53
# Brightness of the flashlight.
FLASHLIGHT_BRIGHTNESS = 10

# Block the weapon inspect animation?
BLOCK_ANIMATION = True
# Should the color of the flashlight be based on the player's steamid?
COLOR_FROM_STEAMID = True


# List of vibrant colors.
pretty_colors = []


def load():
"""Called when the plugin gets loaded."""
# Generate 10 vibrant colors, one for each digit from 0 to 9.
pretty_colors.extend(get_pretty_colors(amount=10))


def unload():
"""Called when the plugin gets unloaded."""
for player in PlayerF.cache.values():
try:
# Try to remove the player's flashlight.
player.torch.remove()
except AttributeError:
continue


@ClientCommand('+lookatweapon')
def inspect_weapon(command, index):
"""Called when a player inspects their weapon."""
PlayerF(index).toggle_torch()

if BLOCK_ANIMATION:
return CommandReturn.BLOCK


@OnNetworkedEntityDeleted
def on_networked_entity_deleted(entity):
"""Called when a networked entity gets deleted."""
if 'env_projectedtexture' in entity.classname:
try:
player = PlayerF.from_inthandle(entity.owner_handle)
except (ValueError, OverflowError):
# ValueError: Not a player.
# OverflowError: Invalid 'owner_handle' (-1).
return

player.torch = None
player.torch_enabled = False


class PlayerF(Player):
"""Extended Player class.

Args:
index (int): A valid player index.
caching (bool): Check for a cached instance?

Attributes:
torch (Entity): Entity instance of the 'env_projectedtexture'.
torch_enabled (bool): Is the torch/flashlight turned on?
"""

def __init__(self, index, caching=True):
"""Initializes the object."""
super().__init__(index, caching)

self.torch = None
self.torch_enabled = False

def toggle_torch(self):
"""Toggles the player's flashlight."""
# Flip the flashlight status.
self.torch_enabled = not self.torch_enabled
torch = self.torch

# Is the player missing a flashlight?
if torch is None:
# Should the player's steamid determine the flashlight color?
if COLOR_FROM_STEAMID:
color = pretty_colors[int(self.steamid[-1])]

# Or not?
else:
color = FLASHLIGHT_COLOR

torch = Torch.create(
color=color,
owner_handle=self.inthandle
)
# Usually, when parenting an entity to the player's viewmodel, the
# entity would only be transmitted to that player. However, if the
# entity that we're parenting has the 'FL_EDICT_ALWAYS' flag, it
# should be transmitted to all connected players.
torch.set_parent(Entity.from_inthandle(
self.get_datamap_property_int('m_hViewModel')), -1)

torch.teleport(NULL_VECTOR, NULL_QANGLE)
# Store the instance.
self.torch = torch

torch.call_input('TurnOn' if self.torch_enabled else 'TurnOff')
self.emit_sound(
sample='items/flashlight1.wav',
attenuation=0.8,
volume=0.3
)


class Torch(Entity):
"""Extended Entity class used for creating a flashlight."""
caching = True

@classmethod
def create(cls, color, owner_handle):
"""Creates a colored flashlight.

Args:
color (Color): Color of the flashlight.
owner_handle (int): Inthandle of the owner.
"""
texture = super().create('env_projectedtexture')
texture.owner_handle = owner_handle
texture.set_key_value_color('lightcolor', color)
# Radius of the flashlight.
texture.set_key_value_float('lightfov', FLASHLIGHT_RADIUS)
# Should objects/geometry cast shadows when lit by the flashlight?
texture.set_key_value_bool('enableshadows', False)
# Should the flashlight affect static world geometry?
texture.set_key_value_bool('lightworld', True)
# Speed at which the color changes.
texture.set_key_value_float('colortransitiontime', 100)
# Brightness of the flashlight.
texture.set_key_value_float('brightnessscale', FLASHLIGHT_BRIGHTNESS)
# Set a spawn flag:
# 2: Always Update (moving light)
texture.spawn_flags = 2
texture.spawn()
return texture

def remove(self):
"""Turns the flashlight off before removing it."""
self.call_input('TurnOff')
self.delay(0, super().remove)


def get_pretty_colors(amount):
"""Returns a list of vibrant colors.

Args:
amount (int): How many colors should be generated?

Returns:
list of Color: A list containing Color instances.
"""
colors = []
step = 1 / amount

for hue in range(0, amount):
colors.append(
Color(*(int(255 * x) for x in hsv_to_rgb(step * hue, 1, 1))))

return colors

You toggle the flashlight with your weapon inspect key (F by default) and the settings for the plugin can be found below the imports.
If you have any additional questions, don't hesitate to ask. :smile:
ImageImageImageImageImage
User avatar
daren adler
Senior Member
Posts: 328
Joined: Sat May 18, 2019 7:42 pm

Re: [CS:GO] Color flashlight with adjustable radius

Postby daren adler » Sun Jan 24, 2021 3:21 am

Hello VinciT, :grin: I tryed this in hl2dm, but did not work :frown: , Is it just for cs:go?
User avatar
VinciT
Senior Member
Posts: 331
Joined: Thu Dec 18, 2014 2:41 am

Re: [CS:GO] Color flashlight with adjustable radius

Postby VinciT » Sun Jan 24, 2021 5:13 am

Hi daren, the code above uses the +lookatweapon command for toggling the flashlight, which is only bound by default in CSGO. You can bind that command to a key to get it to work, but we also have to fix how the color based on the player's steamid is handled, as HL2DM uses a different format - steamid3.

Find this line (102):

Syntax: Select all

color = pretty_colors[int(self.steamid[-1])]
And replace -1 with -2. It should now work.. but not completely.

You see, the entity (env_projectedtexture) I used to create the colored flashlight appears to be somewhat broken in HL2DM. Its position will not update until you turn it off and on again. The fix for this issue is done on the client side - making it impossible to fix with SP.

Now that I think about it, one potential way to fix this from the server side would be to create a repeater that constantly turns the flashlight off and on, but I feel like that wouldn't look very good (constant blinking).
ImageImageImageImageImage
jocik
Junior Member
Posts: 7
Joined: Sat Jan 23, 2021 12:07 am
Location: Poland

Re: [CS:GO] Color flashlight with adjustable radius

Postby jocik » Sun Jan 24, 2021 5:29 pm

Hi VinciT,

This is what I was exactly looking for! :) Thank you very much for providing it, I thought it wouldn't be possible to create something like this. I'm so-called beginner in Python in general (I know basics about oop, classes, functions, methods, decorators and so on) but I don't have any prior xp with writing such plugins and here's a question from me (just question, not a request to create such plugin, I want to try it by myself):

Is it possible to create plugin for CS:GO in SP which will:

1) change the skybox for black starry sky
2) place fog
3) make the entire map dark like it would be night (something like in [HL2:DM] Little Silent Hill)
4) balance the team that in CT will be only 1 random person and in T everyone else
5) at beginning of the round freeze only CT for x seconds and totally darken the screen for him so he won't be able to see anything for same amount of time
6) after x seconds freeze T for the rest time of round and unfreze CT
7) Block "buy" for T and let them have only crowbar
8) Make CT immortal

Thanks!
jocik
User avatar
daren adler
Senior Member
Posts: 328
Joined: Sat May 18, 2019 7:42 pm

Re: [CS:GO] Color flashlight with adjustable radius

Postby daren adler » Sun Jan 24, 2021 7:03 pm

Ok. Thank you for the info on it.
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Re: [CS:GO] Color flashlight with adjustable radius

Postby satoon101 » Sun Jan 24, 2021 7:32 pm

  1. Yes. Here is a good thread about skyboxes in CS:GO: viewtopic.php?f=37&t=2427
  2. I believe so. The above link discusses options for fog. I don't think it's as easy to do in CS:GO as it was in HL2:DM or CS:S
  3. I believe so. Again, some things are a lot different in CS:GO compared to other games, but you should be able to change light sources.
  4. Yes, that should be fairly easy to do just changing teams. Be sure to block the ability to manually choose/change teams when new players join.
  5. Yes. There are ways to blind players, including the Fade user message and remove their radar. For freezing a player, make sure you set that after the "freeze-time" (round_freeze_end event will be called when players are unfrozen) at the beginning of the round, otherwise they will unfreeze as normal.
  6. Yes, easy enough to loop through all players and freeze Ts and unfreeze the CT with Player.frozen = True/False
  7. I'm assuming "crowbar" is done with some custom weapons thing. But yes, you can either block the "buy" command, restrict all weapons except whatever "crowbar" is from Ts, or disable/remove T buyzones.
  8. Yes, you can give the CT godmode
Image
jocik
Junior Member
Posts: 7
Joined: Sat Jan 23, 2021 12:07 am
Location: Poland

Re: [CS:GO] Color flashlight with adjustable radius

Postby jocik » Sun Jan 24, 2021 7:39 pm

Thank you satoon! I'll try to work on this, and for sure I'll post some questions here on the way.

Have a great evenig!
jocik
Junior Member
Posts: 7
Joined: Sat Jan 23, 2021 12:07 am
Location: Poland

Re: [CS:GO] Color flashlight with adjustable radius

Postby jocik » Mon Jan 25, 2021 5:49 pm

VinciT, I've just tested the plugin with other players and we can't see other players flashlight.

Also if I turn on the flashlight, then it's automatically turning off for other player.
User avatar
VinciT
Senior Member
Posts: 331
Joined: Thu Dec 18, 2014 2:41 am

Re: [CS:GO] Color flashlight with adjustable radius

Postby VinciT » Tue Jan 26, 2021 1:29 am

This should fix players not being able to see others' flashlights:

Syntax: Select all

# ../flashlight/flashlight.py

# Python
from colorsys import hsv_to_rgb

# Source.Python
from colors import Color
from commands import CommandReturn
from commands.client import ClientCommand
from entities.entity import Entity
from entities.helpers import index_from_pointer
from entities.hooks import EntityCondition, EntityPreHook
from listeners import OnNetworkedEntityDeleted
from mathlib import NULL_VECTOR, NULL_QANGLE
from players.entity import Player


# Color of the flashlight.
FLASHLIGHT_COLOR = Color(255, 255, 255)
# Radius of the flashlight.
FLASHLIGHT_RADIUS = 53
# Brightness of the flashlight.
FLASHLIGHT_BRIGHTNESS = 10

# Block the weapon inspect animation?
BLOCK_ANIMATION = True
# Should the color of the flashlight be based on the player's steamid?
COLOR_FROM_STEAMID = True


# List of vibrant colors.
pretty_colors = []

# Edict flag used for making sure an entity gets transmitted to all clients
# no matter what.
FL_EDICT_ALWAYS = 1<<3

is_projected_texture = EntityCondition.equals_entity_classname(
'env_projectedtexture')


def load():
"""Called when the plugin gets loaded."""
# Generate 10 vibrant colors, one for each digit from 0 to 9.
pretty_colors.extend(get_pretty_colors(amount=10))


def unload():
"""Called when the plugin gets unloaded."""
for player in PlayerF.cache.values():
try:
# Try to remove the player's flashlight.
player.torch.remove()
except AttributeError:
continue


@ClientCommand('+lookatweapon')
def inspect_weapon(command, index):
"""Called when a player inspects their weapon."""
PlayerF(index).toggle_torch()

if BLOCK_ANIMATION:
return CommandReturn.BLOCK


@EntityPreHook(is_projected_texture, 'set_transmit')
def set_transmit_pre(stack_data):
index = index_from_pointer(stack_data[0])

try:
# Does this index belong to a Torch instance?
torch = Torch.cache[index]
except KeyError:
return None

torch.state_flags |= FL_EDICT_ALWAYS


@OnNetworkedEntityDeleted
def on_networked_entity_deleted(entity):
"""Called when a networked entity gets deleted."""
if 'env_projectedtexture' in entity.classname:
try:
player = PlayerF.from_inthandle(entity.owner_handle)
except (ValueError, OverflowError):
# ValueError: Not a player.
# OverflowError: Invalid 'owner_handle' (-1).
return

player.torch = None
player.torch_enabled = False


class PlayerF(Player):
"""Extended Player class.

Args:
index (int): A valid player index.
caching (bool): Check for a cached instance?

Attributes:
torch (Entity): Entity instance of the 'env_projectedtexture'.
torch_enabled (bool): Is the torch/flashlight turned on?
"""

def __init__(self, index, caching=True):
"""Initializes the object."""
super().__init__(index, caching)

self.torch = None
self.torch_enabled = False

def toggle_torch(self):
"""Toggles the player's flashlight."""
# Flip the flashlight status.
self.torch_enabled = not self.torch_enabled
torch = self.torch

# Is the player missing a flashlight?
if torch is None:
# Should the player's steamid determine the flashlight color?
if COLOR_FROM_STEAMID:
color = pretty_colors[int(self.steamid[-1])]

# Or not?
else:
color = FLASHLIGHT_COLOR

torch = Torch.create(
color=color,
owner_handle=self.inthandle
)
# Usually, when parenting an entity to the player's viewmodel, the
# entity would only be transmitted to that player. However, if the
# entity that we're parenting has the 'FL_EDICT_ALWAYS' flag, it
# should be transmitted to all connected players.
torch.set_parent(Entity.from_inthandle(
self.get_datamap_property_int('m_hViewModel')), -1)

torch.teleport(NULL_VECTOR, NULL_QANGLE)
# Store the instance.
self.torch = torch

torch.call_input('TurnOn' if self.torch_enabled else 'TurnOff')
self.emit_sound(
sample='items/flashlight1.wav',
attenuation=0.8,
volume=0.3
)


class Torch(Entity):
"""Extended Entity class used for creating a flashlight."""
caching = True

@classmethod
def create(cls, color, owner_handle):
"""Creates a colored flashlight.

Args:
color (Color): Color of the flashlight.
owner_handle (int): Inthandle of the owner.
"""
texture = super().create('env_projectedtexture')
texture.owner_handle = owner_handle
texture.light_color = color
# Radius of the flashlight.
texture.light_fov = FLASHLIGHT_RADIUS
# Should objects/geometry cast shadows when lit by the flashlight?
texture.enable_shadows = False
# Should the flashlight affect static world geometry?
texture.light_world = True
# Speed at which the color changes.
texture.color_transition_time = 100
# Brightness of the flashlight.
texture.brightness_scale = FLASHLIGHT_BRIGHTNESS
# Set a spawn flag:
# 2: Always Update (moving light)
texture.spawn_flags = 2
texture.spawn()
return texture

def remove(self):
"""Turns the flashlight off before removing it."""
self.call_input('TurnOff')
self.delay(0, super().remove)


def get_pretty_colors(amount):
"""Returns a list of vibrant colors.

Args:
amount (int): How many colors should be generated?

Returns:
list of Color: A list containing Color instances.
"""
colors = []
step = 1 / amount

for hue in range(0, amount):
colors.append(
Color(*(int(255 * x) for x in hsv_to_rgb(step * hue, 1, 1))))

return colors
If it doesn't, then we need to parent the torch/flashlight directly to the player (the facemask attachment point could work) and not their viewmodel.
jocik wrote:Also if I turn on the flashlight, then it's automatically turning off for other player.
I was afraid this might happen and was hoping CSGO didn't have the limit of only 1 env_projectedtexture like the rest of Valve's games.. We could, however, try using a point_spotlight instead. It might not look as good, but it can get the job done. I'll see what I can do about it in a few hours.
ImageImageImageImageImage
jocik
Junior Member
Posts: 7
Joined: Sat Jan 23, 2021 12:07 am
Location: Poland

Re: [CS:GO] Color flashlight with adjustable radius

Postby jocik » Sun Jan 15, 2023 6:52 pm

Hello @VinciT!

It's been a while! :D

Have you managed to figure something out for above request?

Return to “Plugin Requests”

Who is online

Users browsing this forum: No registered users and 35 guests