Skip to content

Commit

Permalink
Enable auto attaching or detaching the silencer for weapons that can …
Browse files Browse the repository at this point in the history
…be silenced (CS:GO)

With this commit, the plugin remembers the player's choice for the
silencer. This means, that when a player has detached the silencer using
ATTACK2 (right clicking), the corresponding weapon will be spawned
without the silencer attached.

Each inventory will be handled separately!

Affects the following weapons:
* weapon_m4a1_silencer
* weapon_usp_silencer

It does not work for CS:S, however.

Signed-off-by: BackRaw <backraw@gmx.de>
  • Loading branch information
BackRaw committed Dec 1, 2017
1 parent c9764d4 commit 1c75bb2
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 20 deletions.
2 changes: 0 additions & 2 deletions addons/source-python/data/plugins/udm/weapons/cstrike.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

[secondary]
usp = "USP"
# usp_silenced = "USP Silenced"
glock = "Glock 18c"
deagle = "Desert Eeagle"
p228 = "P228"
Expand All @@ -11,7 +10,6 @@ elite = "Elite Dual Berettas"

[primary]
m4a1 = "M4A1"
# m4a1_silenced = "M4A1 Silenced"
ak47 = "AK47"
awp = "AWP"
scout = "Scout"
Expand Down
42 changes: 40 additions & 2 deletions addons/source-python/plugins/udm/players/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# Colors
from colors import Color
from colors import WHITE
# Core
from core import GAME_NAME
# Engines
from engines.server import global_vars
# Filters
Expand Down Expand Up @@ -141,11 +143,42 @@ def equip_inventory_item(self, tag):
weapon.remove()

# Equip the weapon which should be equipped
self.give_weapon(inventory_item.data.name)
weapon = self.give_weapon(inventory_item.data.name)

# Give the weapon if none was found at `tag`
else:
self.give_weapon(inventory_item.data.name)
weapon = self.give_weapon(inventory_item.data.name)

# Get the weapon data for the weapon
weapon_data = weapon_manager.by_name(weapon.weapon_name)

# Set default silencer option if the weapon can be silenced
if weapon_data.can_silence and inventory_item.silencer_option is None:
inventory_item.silencer_option = GAME_NAME == 'csgo'

# Attach or detach the silencer of the weapon
elif inventory_item.silencer_option is not None:
weapon.set_property_bool('m_bSilencerOn', inventory_item.silencer_option)

# Cycle through the player's weapons in the right order to fix the issue with the silencer
# not "physically" being attached
if len(self.inventory) > 1:
for tag in self.inventory.keys():
weapon = self.get_weapon(is_filters=tag)

if weapon is None:
continue

self.client_command(f'use {weapon.classname}', True)

# Cycle to the grenade or knife and back, if the player only has one inventory item
else:
if self.get_weapon(classname='weapon_hegrenade') is not None:
self.client_command('use weapon_hegrenade', True)
else:
self.client_command('use weapon_knife', True)

self.client_command(f'use {weapon.classname}', True)

def equip_random_weapons(self):
"""Equip random weapons by weapon tag."""
Expand Down Expand Up @@ -267,6 +300,11 @@ def carries_inventory(self):
if item.data.name not in (weapon_equipped.weapon_name, weapon_equipped.classname):
return False

# Return False if the weapon is in a different silencer state than it's supposed to be
if item.silencer_option is not None and item.silencer_option !=\
weapon_equipped.get_property_bool('m_bSilencerOn'):
return False

# Return True if the player carries all the weapons in their selected inventory
return True

Expand Down
3 changes: 3 additions & 0 deletions addons/source-python/plugins/udm/players/inventories.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ def __init__(self):
# Make it possible to store the weapon's basename in the future
self.basename = None

# Store the silencer option for this inventory item
self.silencer_option = None

@property
def data(self):
"""Return the weapon's data."""
Expand Down
25 changes: 22 additions & 3 deletions addons/source-python/plugins/udm/udm.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
from listeners import OnServerOutput
# Memory
from memory import make_object
# Players
from players.constants import PlayerButtons
# Weapons
from weapons.entity import Weapon

Expand Down Expand Up @@ -330,12 +332,29 @@ def on_entity_spawned(base_entity):

@OnPlayerRunCommand
def on_player_run_command(player, cmd):
"""Refill the player's active weapon's ammo as soon as the player stops shooting a weapon with an empty clip."""
"""Handle player buttons ATTACK (left click) and ATTACK2 (right click)."""
if player.active_weapon is not None:

# Get the weapon data for the player's active weapon
weapon_data = weapon_manager.by_name(player.active_weapon.weapon_name)

if weapon_data is not None and player.active_weapon.clip == 0:
PlayerEntity(player.index).refill_ammo()
# Handle only valid weapons
if weapon_data is not None:

# Get a PlayerEntity instance for the player
player = PlayerEntity(player.index)

# Refill the weapon's ammo after the reload animation has finished, if the player shoots an empty clip
if player.active_weapon.clip == 0:
player.refill_ammo()

# Handle auto-silencing for the weapon, if the player is attaching or detaching the silencer
elif cmd.buttons & PlayerButtons.ATTACK2 and weapon_data.can_silence:

for inventory_item in player.inventory.values():
if inventory_item.basename == weapon_data.basename:
inventory_item.silencer_option = not player.active_weapon.get_property_bool('m_bSilencerOn')
break


@OnServerActivate
Expand Down
27 changes: 14 additions & 13 deletions addons/source-python/plugins/udm/weapons/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,25 @@ def __init__(self, basename, weapon_class, display_name, tag):
# Store the weapon's primary tag
self._tag = tag

# Store whether the weapon should be silenced
self._silenced = basename.endswith('_silenced')

@property
def basename(self):
"""Return the weapon's basename."""
return self._basename

@property
def can_silence(self):
"""Return whether the weapon can be silenced."""
if 'usp' in self.basename:
return True

if self.basename == 'm4a1_silencer':
return True

if GAME_NAME == 'cstrike' and self.basename == 'm4a1':
return True

return False

@property
def clip(self):
"""Return the weapon's clip."""
Expand All @@ -104,11 +115,6 @@ def name(self):
"""Return the weapon's full name."""
return self._name

@property
def silenced(self):
"""Return whether the weapon should be silenced."""
return self._silenced

@property
def tag(self):
"""Return the weapon's primary tag."""
Expand Down Expand Up @@ -154,11 +160,6 @@ def by_name(self, name):

return None

def silencer_allowed(self, basename):
"""Return whether the weapon of classname `name` is allowed to be silenced."""
weapon_name = basename.replace('_silenced', '')
return weapon_name in self.keys() and f'{weapon_name}_silenced' in self.keys()

@property
def tags(self):
"""Return the tags provided by the weapon data file."""
Expand Down

0 comments on commit 1c75bb2

Please sign in to comment.