Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
I want to disable the ambient sounds. you know the 1shot_droneboys and the growls and x_acient blah blah...
Where in the cgame does that happen. I looked through the EV_BLAH and i tried to search the code for ambient target_speakers and world sounds...
but thats not it.
if i could find it i think this time i could handle the cvar for it.
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
Thanks ill try it and i share my findings!
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
/* ================== CG_EntityEffects
Add continuous entity effects, like local entity emission and lighting ================== */ static void CG_EntityEffects(centity_t * cent) {
// update sound origins CG_SetEntitySoundPosition(cent);
// add loop sound /* if (cent->currentState.loopSound) { if (cent->currentState.eType != ET_SPEAKER) { trap_S_AddLoopingSound(cent->currentState.number, cent->lerpOrigin, vec3_origin, cgs.gameSounds[cent->currentState.loopSound]); } else { trap_S_AddRealLoopingSound(cent->currentState.number, cent->lerpOrigin, vec3_origin, cgs.gameSounds[cent->currentState. loopSound]); } } */
// constant light glow if (cent->currentState.constantLight) { int cl; int i, r, g, b;
cl = cent->currentState.constantLight; r = cl & 255; g = (cl >> 8) & 255; b = (cl >> 16) & 255; i = ((cl >> 24) & 255) * 4; trap_R_AddLightToScene(cent->lerpOrigin, i, r, g, b); }
} Commenting that took care of the flames and wind computer blips But lets say for instance you load up q3dm1 (there is a world drone on this map every 15 seconds or so) after commenting out this section that drone still happens. So I commented the entirety of cg speaker and I still got the world drone on dm1
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
so I added this if (cent->currentState.loopSound) { if ( s_ambient.integer != 0 ) { if (cent->currentState.eType != ET_SPEAKER) { trap_S_AddLoopingSound(cent->currentState.number, cent->lerpOrigin, vec3_origin, cgs.gameSounds[cent->currentState.loopSound]); } else { trap_S_AddRealLoopingSound(cent->currentState.number, cent->lerpOrigin, vec3_origin, cgs.gameSounds[cent->currentState. loopSound]); } } } but if its s_ambient 0 and you change it to 1 it will turn on but not back off... unless you do snd_restart or map_restart
|
|
« Last Edit: 2016-03-19, 16:18 by Orbital-S2D »
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
{&cg_ambients, "cg_ambients", "1", CVAR_ARCHIVE}, I had changed it from s_ambient to cg_ambients case EV_GENERAL_SOUND: DEBUGNAME("EV_GENERAL_SOUND"); if (cgs.gameSounds[es->eventParm]) { //trap_S_StartSound(NULL, es->number, CHAN_VOICE, // cgs.gameSounds[es->eventParm]); } else { s = CG_ConfigString(CS_SOUNDS + es->eventParm); //trap_S_StartSound(NULL, es->number, CHAN_VOICE, // CG_CustomSound(es->number, s)); } break;
case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes DEBUGNAME("EV_GLOBAL_SOUND"); if (cgs.gameSounds[es->eventParm]) { //trap_S_StartSound(NULL, cg.snap->ps.clientNum, CHAN_AUTO, // cgs.gameSounds[es->eventParm]); } else { s = CG_ConfigString(CS_SOUNDS + es->eventParm); //trap_S_StartSound(NULL, cg.snap->ps.clientNum, CHAN_AUTO, // CG_CustomSound(es->number, s)); } break;
doors had no sound some stuff was silent best example is q3dm0 "announcer" welcome, jump here, gladiators goal, all gone bleh it worked better the other way.
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
ok im not sure what I am looking at here :S I see the target speaker and I read this A global sound will play full volume throughout the level.so this would be the x_drones? Activator sounds will play on the player that activated the target.this would be the "welcome to q3a" in dm0? Global and activator sounds can't be combined with looping.not sure what they mean here are doors and powerups global sounds? Normal sounds play each time the target is used.door switch teleporter? Looped sounds will be toggled by use functions. Multiple identical looping sounds will just increase volume without any speed cost. "wait" : Seconds between auto triggerings, 0 = don't auto trigger "random" wait variance, default is 0This is proving quite challenging for me but it is fun. I hope you don't mine me asking for your help so much and you can pick on me about it cause I am a noob! I have had no formal c training but I have changed quite a bit by trial and error.
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Phoenix
|
ok im not sure what I am looking at here :S I see the target speaker
and I read this A global sound will play full volume throughout the level. so this would be the x_drones?
Probably. It would be any sound that plays the same volume no matter where you are as opposed to a sound that would emanate from a specific source - say, a computer console beeping that's louder as you're closer to it.Activator sounds will play on the player that activated the target. this would be the "welcome to q3a" in dm0? Correct.Global and activator sounds can't be combined with looping. not sure what they mean here are doors and powerups global sounds? No. What this means is you can't use the same code to trigger looping sounds. If you check the ent->s.loopsounds toggles, you'll see those are not event driven, those are an entityState flag that's being turned on and off. Global sounds use EV_GLOBAL_SOUND and, and activator sounds use EV_GENERAL_SOUND. An activator sound will play at full volume in the player's ear ("Jump here to reach the armor"), whereas an EV_GENERAL_SOUND that is not an activator sound will play at a specific location instead of following the player's movement.Normal sounds play each time the target is used. door switch teleporter? This is where you need to look a bit deeper into the code. Let's look at doors. Doors are classified as a mover, in g_movers.c, function is:
void SP_func_door (gentity_t *ent) {
You'll notice these lines of code in there:
ent->sound1to2 = ent->sound2to1 = G_SoundIndex("sound/movers/doors/dr1_strt.wav"); ent->soundPos1 = ent->soundPos2 = G_SoundIndex("sound/movers/doors/dr1_end.wav");
Those variables are referenced somewhere, so where? There's this clue:
InitMover( ent );
That's a function call that does stuff to this ent, so let's look at it. Here's the definition:
void InitMover( gentity_t *ent ) {
OK, down in that function we'll find these lines:
ent->use = Use_BinaryMover; ent->reached = Reached_BinaryMover;
Those are function calls set on our door, so let's see what Use_BinaryMover has in it:
void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
and down below we find this:
// starting sound if ( ent->sound1to2 ) { G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 ); }
Aha! It's adding an EV_GENERAL_SOUND, and playing the "ent->sound1to2" sound that was set in SP_func_door. That means that the door sounds are sending an EV_GENERAL_SOUND, but it is NOT being called by "Use_Target_Speaker". Therefore, turning off the sound events in Use_Target_Speaker will not break door sounds, and also explains why disabling "EV_GENERAL_SOUND" on the client DOES break door sounds: They use the same event number, but are initiated from different places on the server-side code.This is proving quite challenging for me but it is fun. I hope you don't mine me asking for your help so much and you can pick on me about it cause I am a noob! I have had no formal c training but I have changed quite a bit by trial and error. That's how I started out, and why I'm helping you in this manner. The more you learn about how and why the code does something the better you become and bending it to your will. I won't write someone's mod for them, but I'm always willing to help someone learn how to do things.
Also, you're not a noob. You're a newbie. There's a difference. A newbie is someone new at something. A noob is a derogatory term for an unskilled player.
|
|
|
Logged
|
I fly into the night, on wings of fire burning bright...
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
OK so I thought about things here... So I loaded up my good ole rusty trusty q3a 1.32c install that I keep zipped up... (the gamma sucks) I played around a bit with CPMA from where this idea is derived from and here is what I have learned With CPMA's s_ambient 0 on q3tourney5 the 1shot_droneboys_01.wav that has its entity in the sky can be heard but the fire sounds cannot. q3dm0 the x_rumbledrone.wav (I think that's the one) can be heard as well as the announcer (welcome jump portal). q3wcp10 this map has two entities in each base that use 1shot_droneboys_01 in the flag room some where around the ceiling light fixture. with s_ambient 0 this map is quiet. in the code it says global sounds cant be combined with looping is this y 1shot only plays once on tourney5? never mind that's not the case. it plays after you walk up the stairs in the center of the map near the rocket launcher. so therefore it is an activator. Now from a mapping perspective how do you put sounds on a map like these? I'm curious because if I can find this then I could find it in the code maybe? are the entities on a map called something similar in the code? what exactly is a speaker? thanks for calling me a newbie!
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Phoenix
|
A speaker is a paper cone with a magnet that produces sound, or someone standing at a lectern trying desperately to sway opinions.
For Q3 purposes, target_speaker is a function that, when triggered, causes a sound to be played on the client. That's its sole function. It's placed on maps as an entity in q3radiant named, not surprisingly, "target_speaker".
If you want to try disabling those, do this like I said before and see what happens:
void Use_Target_Speaker (gentity_t *ent, gentity_t *other, gentity_t *activator) {
// Phoenix - temporarily disabling this return; // End Phoenix test
if (ent->spawnflags & 3) { // looping sound toggles if (ent->s.loopSound) ent->s.loopSound = 0; // turn it off else ent->s.loopSound = ent->noise_index; // start it }else { // normal sound if ( ent->spawnflags & 8 ) { G_AddEvent( activator, EV_GENERAL_SOUND, ent->noise_index ); } else if (ent->spawnflags & 4) { G_AddEvent( ent, EV_GLOBAL_SOUND, ent->noise_index ); } else { G_AddEvent( ent, EV_GENERAL_SOUND, ent->noise_index ); } } }
|
|
|
Logged
|
I fly into the night, on wings of fire burning bright...
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
A speaker is a paper cone with a magnet that produces sound, or someone standing at a lectern trying desperately to sway opinions.
Oh burn!!! I left that door open didn't I! You did say to put a return in. I was just trying to do more detective work... I'll try it tonight if I can.
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
OK that was cool... that disabled everything we want but nothing we don't
except on q3ctf2 the water...
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
Could you explain what we did there? What is that bit of code saying...
Break it down for me cause I want to make sure I am understanding what it is actually saying. I don't want to assume
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
Yea that killed the majority of it there is still some like the water gurgling on q3ctf2... but that was the majority of it yes
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
yes please continue
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Phoenix
|
Patience, tiny grasshopper. Sometimes the bird is away, busy, and/or sleeping.
Since we've determined that target_speaker is sending these sounds, we need to see how we can separate a target_speaker out from other entities. Fortunately, this has already been done for us. In SP_target_speaker, we can see this line:
ent->s.eType = ET_SPEAKER;
Anything on the right side of ent->s. is part of the "entitystate_t" structure. Entitystate_t is what gets sent to the client. In this case, all entities that are spawned from SP_target_speaker have an eType of "ET_SPEAKER". This means we can test for this on the client.
First, let's look at looping sounds. In cg_ents, we find this:static void CG_EntityEffects( centity_t *cent ) {
// update sound origins CG_SetEntitySoundPosition( cent );
// add loop sound if ( cent->currentState.loopSound ) { if (cent->currentState.eType != ET_SPEAKER) { trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, cgs.gameSounds[ cent->currentState.loopSound ] ); } else { trap_S_AddRealLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, cgs.gameSounds[ cent->currentState.loopSound ] ); } }
// constant light glow if ( cent->currentState.constantLight ) { int cl; int i, r, g, b;
cl = cent->currentState.constantLight; r = cl & 255; g = ( cl >> 8 ) & 255; b = ( cl >> 16 ) & 255; i = ( ( cl >> 24 ) & 255 ) * 4; trap_R_AddLightToScene( cent->lerpOrigin, i, r, g, b ); }
}
You'll notice a conditional test for ET_SPEAKER is present. In this case, it's testing for != ET_SPEAKER. So the first part of the "if" statement is generating looping sounds for all entities except ET_SPEAKER. The "else" part is only concerned with ET_SPEAKER. What we can do then is this. Assuming that your cvar is called "cg_ambient": // add loop sound if ( cent->currentState.loopSound ) { if (cent->currentState.eType != ET_SPEAKER) { trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, cgs.gameSounds[ cent->currentState.loopSound ] ); } else { if (cg_ambient.integer > 0 ){ trap_S_AddRealLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, cgs.gameSounds[ cent->currentState.loopSound ] ); } }
That would enable the looping sounds on ET_SPEAKER entities only if your cvar is not == 0.
OK, now what about the events? We'll look at cg_event, and here they are: case EV_GENERAL_SOUND: DEBUGNAME("EV_GENERAL_SOUND"); if ( cgs.gameSounds[ es->eventParm ] ) { trap_S_StartSound (NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) ); } break;
case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes DEBUGNAME("EV_GLOBAL_SOUND"); if ( cgs.gameSounds[ es->eventParm ] ) { trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound( es->number, s ) ); } break;
All we have to do is put in conditional tests for the ET_SPEAKER. Now you'll need to pay attention to the entitystate structure, which in this case is "es". So you'll see es->eventParm on the client is the same as ent->s.eventParm on the server. That means to test for eType, we'll use es->eType, like so: case EV_GENERAL_SOUND: DEBUGNAME("EV_GENERAL_SOUND"); // Phoenix - don't play speaker sounds if disabled. if (es->eType == ET_SPEAKER && cg_ambient.integer == 0){ break; } if ( cgs.gameSounds[ es->eventParm ] ) { trap_S_StartSound (NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) ); } break;
case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes DEBUGNAME("EV_GLOBAL_SOUND"); // Phoenix - don't play speaker sounds if disabled. if (es->eType == ET_SPEAKER && cg_ambient.integer == 0){ break; } if ( cgs.gameSounds[ es->eventParm ] ) { trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound( es->number, s ) ); } break;
You'll see that we're breaking out of the case statement if the sound event is occuring on a speaker entity and we have our ambient variable disabled.
Now in theory, and provided I didn't screw anything up, that should give you the ability to toggle any sounds caused by an ET_SPEAKER on and off using a client-side cvar. That won't disable the water on that CTF map because that's being caused by something else, but one step at a time. See if this scenario works for you and let me know what happens.
|
|
|
Logged
|
I fly into the night, on wings of fire burning bright...
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
Patience, tiny grasshopper. Sometimes the bird is away, busy, and/or sleeping. I did not mean to sound like i was rushing you at all... sorry i am eager to learn though. this is fun So now i have questions. This, if (cg_ambient.integer > 0 ) So what would happen if it was the integer was set too 2? Doesn't > 0 mean anything but 0. what if it was == 1 instead of > 0 i ask this because if (es->eType == ET_SPEAKER && cg_ambient.integer == 0){ break; The break; . Does that mean that if the integer was 0 then continue on too the next if statement. If not equal to 0 skip the rest?
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
|