S_StartSound(32768 + PRVM_NUM_FOR_EDICT(entity), channel, S_FindName(sample), entity->fields.client->origin, volume, attenuation);
}
+// #483 void(vector origin, string sample, float volume, float attenuation) pointsound
+static void VM_CL_pointsound(void)
+{
+ const char *sample;
+ float volume;
+ float attenuation;
+ vec3_t org;
+
+ VM_SAFEPARMCOUNT(4, VM_CL_pointsound);
+
+ VectorCopy( PRVM_G_VECTOR(OFS_PARM0), org);
+ sample = PRVM_G_STRING(OFS_PARM1);
+ volume = PRVM_G_FLOAT(OFS_PARM2);
+ attenuation = PRVM_G_FLOAT(OFS_PARM3);
+
+ if (volume < 0 || volume > 1)
+ {
+ VM_Warning("VM_CL_pointsound: volume must be in range 0-1\n");
+ return;
+ }
+
+ if (attenuation < 0 || attenuation > 4)
+ {
+ VM_Warning("VM_CL_pointsound: attenuation must be in range 0-4\n");
+ return;
+ }
+
+ // Send World Entity as Entity to Play Sound (for CSQC, that is 32768)
+ S_StartSound(32768, 0, S_FindName(sample), org, volume, attenuation);
+}
+
// #14 entity() spawn
static void VM_CL_spawn (void)
{
VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
-NULL, // #483
+VM_CL_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
NULL, // #484
NULL, // #485
NULL, // #486
void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count);
void SV_StartEffect (vec3_t org, int modelindex, int startframe, int framecount, int framerate);
void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int volume, float attenuation);
+void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float attenuation);
void SV_ConnectClient (int clientnum, netconn_t *netconnection);
void SV_DropClient (qboolean crash);
SV_FlushBroadcastMessages();
}
+/*
+==================
+SV_StartPointSound
+
+Nearly the same logic as SV_StartSound, except an origin
+instead of an entity is provided and channel is omitted.
+
+The entity sent to the client is 0 (world) and the channel
+is 0 (CHAN_AUTO). SND_LARGEENTITY will never occur in this
+function, therefore the check for it is omitted.
+
+==================
+*/
+void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float attenuation)
+{
+ int sound_num, field_mask, i;
+
+ if (volume < 0 || volume > 255)
+ {
+ Con_Printf ("SV_StartPointSound: volume = %i\n", volume);
+ return;
+ }
+
+ if (attenuation < 0 || attenuation > 4)
+ {
+ Con_Printf ("SV_StartPointSound: attenuation = %f\n", attenuation);
+ return;
+ }
+
+ if (sv.datagram.cursize > MAX_PACKETFRAGMENT-21)
+ return;
+
+ // find precache number for sound
+ sound_num = SV_SoundIndex(sample, 1);
+ if (!sound_num)
+ return;
+
+ field_mask = 0;
+ if (volume != DEFAULT_SOUND_PACKET_VOLUME)
+ field_mask |= SND_VOLUME;
+ if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION)
+ field_mask |= SND_ATTENUATION;
+ if (sound_num >= 256)
+ field_mask |= SND_LARGESOUND;
+
+// directed messages go only to the entity they are targeted on
+ MSG_WriteByte (&sv.datagram, svc_sound);
+ MSG_WriteByte (&sv.datagram, field_mask);
+ if (field_mask & SND_VOLUME)
+ MSG_WriteByte (&sv.datagram, volume);
+ if (field_mask & SND_ATTENUATION)
+ MSG_WriteByte (&sv.datagram, (int)(attenuation*64));
+ // Always write entnum 0 for the world entity
+ MSG_WriteShort (&sv.datagram, (0<<3) | 0);
+ if (field_mask & SND_LARGESOUND)
+ MSG_WriteShort (&sv.datagram, sound_num);
+ else
+ MSG_WriteByte (&sv.datagram, sound_num);
+ for (i = 0;i < 3;i++)
+ MSG_WriteCoord (&sv.datagram, origin[i], sv.protocol);
+ SV_FlushBroadcastMessages();
+}
+
/*
==============================================================================
"DP_SV_PING "
"DP_SV_PLAYERPHYSICS "
"DP_SV_POINTPARTICLES "
+"DP_SV_POINTSOUND "
"DP_SV_PRECACHEANYTIME "
"DP_SV_PRINT "
"DP_SV_PUNCHVECTOR "
SV_StartSound (entity, channel, sample, volume, attenuation);
}
+/*
+=================
+VM_SV_pointsound
+
+Follows the same logic as VM_SV_sound, except instead of
+an entity, an origin for the sound is provided, and channel
+is omitted (since no entity is being tracked).
+
+=================
+*/
+static void VM_SV_pointsound(void)
+{
+ const char *sample;
+ int volume;
+ float attenuation;
+ vec3_t org;
+
+ VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
+
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+ sample = PRVM_G_STRING(OFS_PARM1);
+ volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
+ attenuation = PRVM_G_FLOAT(OFS_PARM3);
+
+ if (volume < 0 || volume > 255)
+ {
+ VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
+ return;
+ }
+
+ if (attenuation < 0 || attenuation > 4)
+ {
+ VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
+ return;
+ }
+
+ SV_StartPointSound (org, sample, volume, attenuation);
+}
+
/*
=================
VM_SV_traceline
VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
-NULL, // #483
+VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
NULL, // #484
NULL, // #485
NULL, // #486