Skip to content

Commit c8547a7

Browse files
author
L'In20Cible
committed
Added Entity.emit_sound, Player.play_sound and Player.stop_sound.
1 parent 9335510 commit c8547a7

File tree

3 files changed

+122
-2
lines changed

3 files changed

+122
-2
lines changed

addons/source-python/packages/source-python/engines/sound.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929
from entities.constants import INVALID_ENTITY_INDEX
3030
# Filesystem
3131
from filesystem import SourceFile
32-
# Filters
33-
from filters.recipients import RecipientFilter
3432
# Mathlib
3533
from mathlib import NULL_VECTOR
3634
# Paths
@@ -146,6 +144,9 @@ def __init__(
146144

147145
def play(self, *recipients):
148146
"""Play the sound."""
147+
# Done here to fix a cyclic import...
148+
from filters.recipients import RecipientFilter
149+
149150
# Get the recipients to play the sound to
150151
recipients = RecipientFilter(*recipients)
151152

addons/source-python/packages/source-python/entities/entity.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,17 @@
1212
# Source.Python Imports
1313
# Core
1414
from core import GAME_NAME
15+
# Entities
16+
from entities.constants import INVALID_ENTITY_INDEX
1517
# Engines
1618
from engines.precache import Model
19+
from engines.sound import Attenuation
20+
from engines.sound import Channel
21+
from engines.sound import Pitch
22+
from engines.sound import Sound
23+
from engines.sound import SoundFlags
24+
from engines.sound import StreamSound
25+
from engines.sound import VOL_NORM
1726
from engines.trace import engine_trace
1827
from engines.trace import ContentMasks
1928
from engines.trace import GameTrace
@@ -31,6 +40,8 @@
3140
from entities.helpers import wrap_entity_mem_func
3241
# Filters
3342
from filters.weapons import WeaponClassIter
43+
# Mathlib
44+
from mathlib import NULL_VECTOR
3445
# Memory
3546
from memory import get_object_pointer
3647
from memory import make_object
@@ -502,6 +513,52 @@ def lookup_attachment(self, name):
502513
# No attachment found
503514
return INVALID_ATTACHMENT_INDEX
504515

516+
def emit_sound(
517+
self, sample, recipients=(), volume=VOL_NORM,
518+
attenuation=Attenuation.NONE, channel=Channel.AUTO,
519+
flags=SoundFlags.NO_FLAGS, pitch=Pitch.NORMAL, origin=NULL_VECTOR,
520+
direction=NULL_VECTOR, origins=(), update_positions=True,
521+
sound_time=0.0, speaker_entity=INVALID_ENTITY_INDEX,
522+
download=False, stream=False):
523+
"""Emit a sound from this entity.
524+
525+
:param str sample: Sound file relative to the "sounds" directory.
526+
:param RecipientFilter recipients: Recipients to emit the sound to.
527+
:param int index: Index of the entity to emit the sound from.
528+
:param float volume: Volume of the sound.
529+
:param Attenuation attenuation: How far the sound should reaches.
530+
:param int channel: Channel to emit the sound with.
531+
:param SoundFlags flags: Flags of the sound.
532+
:param Pitch pitch: Pitch of the sound.
533+
:param Vector origin: Origin of the sound.
534+
:param Vector direction: Direction of the sound.
535+
:param tuple origins: Origins of the sound.
536+
:param bool update_positions: Whether or not the positions should be
537+
updated.
538+
:param float sound_time: Time to play the sound for.
539+
:param int speaker_entity: Index of the speaker entity.
540+
:param bool download: Whether or not the sample should be added to the
541+
downloadables.
542+
:param bool stream: Whether or not the sound should be streamed.
543+
"""
544+
# Get the correct Sound class...
545+
if not stream:
546+
sound_class = Sound
547+
else:
548+
sound_class = StreamSound
549+
550+
# Get the sound...
551+
sound = sound_class(sample, self.index, volume, attenuation, channel,
552+
flags, pitch, origin, direction, origins, update_positions,
553+
sound_time, speaker_entity, download)
554+
555+
# Make sure we have a tuple as recipients...
556+
if not isinstance(recipients, tuple):
557+
recipients = (recipients,)
558+
559+
# Emit the sound to the given recipients...
560+
sound.play(*recipients)
561+
505562
def is_in_solid(
506563
self, mask=ContentMasks.ALL, generator=BaseEntityGenerator):
507564
"""Return whether or not the entity is in solid."""

addons/source-python/packages/source-python/players/_base.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@
1919
from engines.server import engine_server
2020
from engines.server import execute_server_command
2121
from engines.server import server_game_dll
22+
from engines.sound import Attenuation
23+
from engines.sound import Channel
24+
from engines.sound import engine_sound
25+
from engines.sound import Pitch
26+
from engines.sound import Sound
27+
from engines.sound import SoundFlags
28+
from engines.sound import SOUND_FROM_WORLD
29+
from engines.sound import StreamSound
30+
from engines.sound import VOL_NORM
2231
from engines.trace import engine_trace
2332
from engines.trace import ContentMasks
2433
from engines.trace import GameTrace
@@ -39,6 +48,7 @@
3948
# Filters
4049
from filters.entities import EntityIter
4150
# Mathlib
51+
from mathlib import NULL_VECTOR
4252
from mathlib import Vector
4353
from mathlib import QAngle
4454
# Memory
@@ -619,6 +629,58 @@ def ban(self, duration=0, kick=True, write_ban=True):
619629
if write_ban:
620630
execute_server_command('writeid')
621631

632+
def play_sound(
633+
self, sample, volume=VOL_NORM, attenuation=Attenuation.NONE,
634+
channel=Channel.AUTO, flags=SoundFlags.NO_FLAGS,
635+
pitch=Pitch.NORMAL, origin=NULL_VECTOR, direction=NULL_VECTOR,
636+
origins=(), update_positions=True, sound_time=0.0,
637+
speaker_entity=INVALID_ENTITY_INDEX, download=False,
638+
stream=False):
639+
"""Play a sound to the player.
640+
641+
:param str sample: Sound file relative to the "sounds" directory.
642+
:param float volume: Volume of the sound.
643+
:param Attenuation attenuation: How far the sound should reaches.
644+
:param int channel: Channel to emit the sound with.
645+
:param SoundFlags flags: Flags of the sound.
646+
:param Pitch pitch: Pitch of the sound.
647+
:param Vector origin: Origin of the sound.
648+
:param Vector direction: Direction of the sound.
649+
:param tuple origins: Origins of the sound.
650+
:param bool update_positions: Whether or not the positions should be
651+
updated.
652+
:param float sound_time: Time to play the sound for.
653+
:param int speaker_entity: Index of the speaker entity.
654+
:param bool download: Whether or not the sample should be added to the
655+
downloadables.
656+
:param bool stream: Whether or not the sound should be streamed.
657+
"""
658+
# Don't bother playing sounds to bots...
659+
if self.is_fake_client():
660+
return
661+
662+
# Get the correct Sound class...
663+
if not stream:
664+
sound_class = Sound
665+
else:
666+
sound_class = StreamSound
667+
668+
# Get the sound...
669+
sound = sound_class(sample, SOUND_FROM_WORLD, volume, attenuation,
670+
channel, flags, pitch, origin, direction, origins,
671+
update_positions, sound_time, speaker_entity, download)
672+
673+
# Play the sound to the player...
674+
sound.play(self.index)
675+
676+
def stop_sound(self, sample, channel=Channel.AUTO):
677+
"""Stop the given sound from being played to the player.
678+
679+
:param str sample: Sound file relative to the "sounds" directory.
680+
:param Channel channel: Te channel of the sound.
681+
"""
682+
engine_sound.stop_sound(self.index, channel, sample)
683+
622684
# =========================================================================
623685
# >> PLAYER WEAPON FUNCTIONALITY
624686
# =========================================================================

0 commit comments

Comments
 (0)